Biomechanical Joint Model
 Author: Anderson Maciel

comebiostructure.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  **************************************************************************/
00021 //
00022 //  PROJECT.....: CO-ME
00023 //  RESPONSIBLE.: 
00024 //
00025 //  FILE........: comebiostructure.cpp
00026 //  DESCRIPTION.: 
00027 //                                 
00028 //
00029 //  AUTHOR......: Anderson Maciel
00030 //  DATE........: May/27/2002
00031 //  DESCRIPTION.: Class definition.
00032 //
00034 
00035 #include        <bio/comebiostructure.h>
00036 #include        <general/comescenario.h>
00037 #include        <algebra/comemesh.h>
00038 #include        <RAPID/RAPID.H>
00039 
00040 #include <math.h>
00041 #include <time.h>
00042 
00046 
00047 void
00048 COME_BioStructure::setSystem( int systemN ){
00049 
00050         system = systemN;
00051 }
00052 
00053 void
00054 COME_BioStructure::setSurface( COME_Mesh *surfaceN ){
00055 
00056         surface = surfaceN;
00057         surface->setParent( this );
00058         surface->setCollisionDetectableFaces();
00059 }
00060 
00061 void
00062 COME_BioStructure::setFixed( bool flag ){
00063 
00064         fixed = flag;
00065 }
00066 
00067 void
00068 COME_BioStructure::setLIM( const COME_Matrix &limN ){
00069 
00070         localInstanceMatrix = limN;
00071 }
00072 
00073 void
00074 COME_BioStructure::setGIM( const COME_Matrix &gimN ){
00075 
00076         globalInstanceMatrix = gimN;
00077 }
00078 
00079 void
00080 COME_BioStructure::setGlobalHooke( double hookeN ){
00081 
00082         globalHooke = hookeN;
00083 }
00084 
00085 void
00086 COME_BioStructure::setCollisionRadius( double rad ){
00087 
00088         collisionRadius = rad;
00089 }
00090 
00091 void
00092 COME_BioStructure::setType( int nType ){
00093         
00094         type = nType;
00095 }
00096 
00100         
00101 int
00102 COME_BioStructure::getSystem() const {
00103 
00104         return system;
00105 }
00106 
00107 COME_Mesh*
00108 COME_BioStructure::getSurface() {
00109 
00110         return surface;
00111 }
00112 
00113 COME_Mesh*
00114 COME_BioStructure::getPointerToSurface() {
00115 
00116         return surface;
00117 }
00118 
00119 bool
00120 COME_BioStructure::isFixed() const{
00121 
00122         return fixed;
00123 }
00124 
00125 const COME_Matrix&
00126 COME_BioStructure::getLIM() const {
00127 
00128         return localInstanceMatrix;
00129 }
00130 
00131 const COME_Matrix&
00132 COME_BioStructure::getGIM() const {
00133 
00134         return globalInstanceMatrix;
00135 }
00136 
00137 
00138 double
00139 COME_BioStructure::getGlobalHooke() const {
00140 
00141         return globalHooke;
00142 }
00143 
00144 double
00145 COME_BioStructure::getCollisionRadius() const {
00146 
00147         return collisionRadius;
00148 }
00149 
00150 double
00151 COME_BioStructure::getTopStress() {
00152 
00153         return getTissue()->getTopStress();
00154 }
00155 
00156 void
00157 COME_BioStructure::scale( double factorx, double factory, double factorz ){
00158 
00159         getTissue()->scale( factorx, factory, factorz );
00160         
00161         if( surface ){
00162                 if( isFixed() ){
00163                         surface->scale( factorx, factory, factorz );
00164                 } else {
00165                         getTissue()->makeAllLocalFrames();
00166                         surface->updateSkin();
00167                 }
00168         }
00169         
00170 }
00171 
00172 void
00173 COME_BioStructure::translate( double px, double py, double pz ){
00174 
00175         getTissue()->translate( px, py, pz );
00176         
00177         if( surface ){
00178                 if( isFixed() ){
00179                         surface->translate( px, py, pz );
00180                 } else {
00181                         getTissue()->makeAllLocalFrames();
00182                         surface->updateSkin();
00183                 }
00184         }
00185 }
00186 
00187 void
00188 COME_BioStructure::translate( const COME_Vector3D &disp ){
00189         
00190         translate( disp.getX(), disp.getY(), disp.getZ() );
00191 }
00192 
00193 void
00194 COME_BioStructure::rotate( double rx, double ry, double rz ){
00195 
00196         getTissue()->rotate( rx, ry, rz );
00197         
00198         if( surface ){
00199                 if( isFixed() ){
00200                         surface->rotate( rx, ry, rz );
00201                 } else {
00202                         getTissue()->makeAllLocalFrames();
00203                         surface->updateSkin();
00204                 }
00205         }
00206         
00207 }
00208 
00209 void
00210 COME_BioStructure::scaleNominals( double factor ){
00211 
00212         if( !isFixed() ){
00213                 getTissue()->scaleNominals( factor );
00214         }
00215 }
00216 
00217 void
00218 COME_BioStructure::globalToLocal( COME_Matrix M, COME_Matrix MP ){
00219 
00220         if( getTissue() ){
00221                 if( type == LIGAMENT ){
00222                         getTissue()->transform( M, MP );
00223                 } else {
00224                         getTissue()->transform( M );
00225                 }
00226         } else {
00227                 surface->transform( M );
00228         }
00229 }
00230 
00231 void
00232 COME_BioStructure::initializeHashStructure(){
00233 
00234         clock_t start,end;
00235         start = clock ();
00236         
00238         sUnit = COME_Vector3D( 0.0, 0.0, 1.0 ); 
00239         sSpherical = COME_Point2D( atan2( sUnit.y, sUnit.x ), acos( sUnit.z ) );
00240         hashSize = 20;
00241         
00243         if( hashTable ){
00244                 delete [] hashTable;
00245         } else {
00246                 hashTable = new COME_HashElement[hashSize*hashSize]; //malloc((unsigned) (nrow)*sizeof(double*))) == NULL)
00247         }
00248         
00250         for( int i = 0; i < hashSize; i++ ){
00251                 for( int j = 0; j < hashSize; j++ ){
00252                         hashTable[elem(i,j)].face = NULL;
00253                         hashTable[elem(i,j)].distance = INFINITE;
00254                 }
00255         }
00256         
00257         for( int iF = 0; iF < surface->getNumberFaces(); iF++ ){
00258                 
00259                 COME_Vector3D centerFace; centerFace.setVector3D( surface->getAFacePt(iF)->getCenterGlobalPosition() );
00260                 centerFace.vpNormalize();
00261                 COME_Point2D fSpherical = COME_Point2D( atan2( centerFace.y, centerFace.x ), acos( centerFace.z ) ) - sSpherical;
00262                 int indexX = (int) ( ( fSpherical.getX() * ( ((double)(hashSize-1)) / ( 2.0 * M_PI ) ) ) + ( ((double)(hashSize-1)) / 2.0 ) );
00263                 int indexY = (int) ( ( fSpherical.getY() * ( ((double)(hashSize-1)) / ( M_PI ) ) ) );//  + ( (double)(hashSize-1) / 2.0 ) );
00264                 double distance = surface->getAFacePt(iF)->distancePointFaceGlobal( COME_Point3D() );
00265                 //printf( "i: %d j: %d index: %d \n", indexX,indexY,  elem(indexX,indexY) );
00266                 if( distance < hashTable[elem(indexX,indexY)].distance ){
00267                                 if( ( surface->getAFacePt(iF)->getNormalGlobalPosition().vpDotProduct( centerFace ) < 0.0 ) ) { 
00268                                 hashTable[elem(indexX,indexY)].face = surface->getAFacePt(iF);
00269                                 hashTable[elem(indexX,indexY)].distance = distance;
00270                         }
00271                 }
00272         }
00273         
00274         printf( "Hash completed with %d neighbor elements in 1st pass.\n", fillHashHoles() );
00275         printf( "Hash completed with %d neighbor elements in 2nd pass.\n", fillHashHoles() );
00276         
00277         for( int i = 0; i < hashSize; i++ ){
00278                 for( int j = 0; j < hashSize; j++ ){
00279                         if( hashTable[elem(i,j)].distance > (INFINITE / 10.0) ) { 
00280                                 
00281                                 if( hashTable[elem(i,j)].face ){
00282                                         double cCollided[] = {0.1, 1.0, 0.1, 1.0};
00283                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(0)->setColor( cCollided );
00284                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(1)->setColor( cCollided );
00285                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(2)->setColor( cCollided );
00286                                 }
00287                                 printf( "ZERO " );
00288                         } else{
00289                                 if( hashTable[elem(i,j)].face ){
00290                                         double cCollided[] = {1.0, 1.0, 1.0, 1.0};
00291                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(0)->setColor( cCollided );
00292                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(1)->setColor( cCollided );
00293                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(2)->setColor( cCollided );
00294                                 }
00295                                 printf( "%1.3f ", hashTable[elem(i,j)].distance );
00296                         }
00297                 }
00298                 printf( "\n" );
00299         }
00300         
00301         
00302         end = clock ();
00303         double dif = end - start;
00304         printf ("Init hash for collision time was %.8f seconds.\n", dif / (double) CLOCKS_PER_SEC );
00305 
00306 }
00307 
00308 void
00309 COME_BioStructure::initializeHashStructureRayCasting(){
00310 
00311         clock_t start,end;
00312         start = clock ();
00313         
00315         sUnit = COME_Vector3D( 0.0, 0.0, 1.0 ); 
00316         sSpherical = COME_Point2D( atan2( sUnit.y, sUnit.x ), acos( sUnit.z ) );
00317         hashSize = 40;
00318         
00320         if( hashTable ){
00321                 delete [] hashTable;
00322         } else {
00323                 hashTable = new COME_HashElement[hashSize*hashSize]; //malloc((unsigned) (nrow)*sizeof(double*))) == NULL)
00324         }
00325         
00327         for( int i = 0; i < hashSize; i++ ){
00328                 for( int j = 0; j < hashSize; j++ ){
00329                         
00330                         hashTable[elem(i,j)].face = NULL;
00331                         hashTable[elem(i,j)].distance = INFINITE;
00332                 }
00333         }
00334         
00335         FILE * pFile;
00336         pFile = fopen ("saida.txt","w");
00337         
00339         for( int i = 0; i < hashSize; i++ ){
00340                 for( int j = 0; j < hashSize; j++ ){
00341                         
00342                         // create ray
00343                         double theta = ( ( 2.0 * M_PI * i ) / ((double)( hashSize-1) ) ) - M_PI;
00344                         double phi = ( ( M_PI * j ) / ((double)( hashSize-1) ) );
00345                         
00346                         COME_Vector3D intersectRay( ( 1.0 * cos( theta ) * sin( phi ) ), ( 1.0 * sin( theta ) * sin( phi ) ), ( 1.0 * cos( phi) ) );
00347                         
00348                         //fprintf( pFile, "i: %d j: %d theta: %f phi: %f x: %f y: %f z: %f\n", i, j, theta, phi, intersectRay.x, intersectRay.y, intersectRay.z );
00349                         //printf( "i: %d j: %d theta: %f phi: %f x: %f y: %f z: %f\n", i, j, theta, phi, intersectRay.x, intersectRay.y, intersectRay.z );
00350                         
00351                         // for each face turned to center test intersection with ray
00352                         for( int iF = 0; iF < surface->getNumberFaces(); iF++ ){
00353                 
00354                                 COME_Vector3D centerFace( surface->getAFacePt(iF)->getVertexGlobalPositionPt( 0 )->x, surface->getAFacePt(iF)->getVertexGlobalPositionPt( 0 )->y, surface->getAFacePt(iF)->getVertexGlobalPositionPt( 0 )->z );
00355                                 centerFace.vpNormalize();
00356                                 if( ( surface->getAFacePt(iF)->getNormalGlobalPosition().vpDotProduct( centerFace ) < 0.0 ) ) { 
00357                                         COME_Point3D intersectPoint;
00358                                         if( surface->getAFacePt(iF)->intersectionRayTriangle( intersectRay, intersectPoint ) ) { 
00359                                                 // put intersection onto the table with distance
00360                                                 hashTable[elem(i,j)].face = surface->getAFacePt(iF);
00361                                                 hashTable[elem(i,j)].distance = surface->getAFacePt(iF)->distancePointFaceGlobal( COME_Point3D() );
00362                                                 break;
00363                                         }
00364                                 }
00365                         }
00366                 }
00367         }
00368         
00369         fclose (pFile);
00370         
00371         for( int i = 0; i < hashSize; i++ ){
00372                 for( int j = 0; j < hashSize; j++ ){
00373                         if( hashTable[elem(i,j)].distance > (INFINITE / 10.0) ) { 
00374                                 
00375                                 if( hashTable[elem(i,j)].face ){
00376                                         double cCollided[] = {0.1, 1.0, 0.1, 1.0};
00377                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(0)->setColor( cCollided );
00378                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(1)->setColor( cCollided );
00379                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(2)->setColor( cCollided );
00380                                 }
00381                                 printf( "ZERO " );
00382                         } else{
00383                                 if( hashTable[elem(i,j)].face ){
00384                                         double cCollided[] = {1.0, 1.0, 1.0, 1.0};
00385                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(0)->setColor( cCollided );
00386                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(1)->setColor( cCollided );
00387                                         hashTable[elem(i,j)].face->getVertexGlobalPositionPt(2)->setColor( cCollided );
00388                                 }
00389                                 printf( "%1.3f ", hashTable[elem(i,j)].distance );
00390                         }
00391                 }
00392                 printf( "\n" );
00393         }
00394         
00395         end = clock ();
00396         double dif = end - start;
00397         printf ("Init hash for collision time was %.8f seconds.\n", dif / (double) CLOCKS_PER_SEC );
00398 
00399 }
00400 
00402 COME_HashElement
00403 COME_BioStructure::getHashElement( COME_Point2D p ){
00404 
00405         int indexX = (int) ( ( p.getX() * ( ((double)(hashSize-1)) / ( 2.0 * M_PI ) ) ) + ( ((double)(hashSize-1)) / 2.0 ) );
00406         int indexY = (int) ( ( p.getY() * ( ((double)(hashSize-1)) / (  M_PI ) ) ) );// + ( (double)(hashSize-1) / 2.0 ) );
00407 
00408         return hashTable[elem(indexX,indexY)];
00409 }
00410 
00411 
00412 int
00413 COME_BioStructure::fillHashHoles(){
00414 
00415         int countAdditions = 0;
00416         COME_HashElement rowElement, columnElement;
00417         
00418         for( int i = 1; i < hashSize-1; i++ ){
00419                 for( int j = 1; j < hashSize-1; j++ ){
00420                 
00421                         rowElement.distance = columnElement.distance = INFINITE;
00422                         rowElement.face = columnElement.face = NULL;
00423         
00424                         if( !(hashTable[elem(i,j)].face) ){
00425                                 for( int rowS = i-1; rowS >= 0; rowS-- ){
00426                                         if( hashTable[elem(rowS,j)].face ){
00427                                                 for( int rowF = i+1; rowF < hashSize; rowF++ ){
00428                                                         if( hashTable[elem(rowF,j)].face ){
00429                                                                 rowElement = ( hashTable[elem(rowS,j)].distance < hashTable[elem(rowF,j)].distance ) ? hashTable[elem(rowS,j)] : hashTable[elem(rowF,j)];
00430                                                                 break;
00431                                                         }
00432                                                 }
00433                                                 break;
00434                                         }
00435                                 }
00436                                 
00437                                 for( int colS = j-1; colS >= 0; colS-- ){
00438                                         if( hashTable[elem(i,colS)].face ){
00439                                                 for( int colF = j+1; colF < hashSize; colF++ ){
00440                                                         if( hashTable[elem(i,colF)].face ){
00441                                                                 columnElement = ( hashTable[elem(i,colS)].distance < hashTable[elem(i,colF)].distance ) ? hashTable[elem(i,colS)] : hashTable[elem(i,colF)];
00442                                                                 break;
00443                                                         }
00444                                                 }
00445                                                 break;
00446                                         }
00447                                 }
00448                                 
00449                                 if( rowElement.face || columnElement.face ) countAdditions++;
00450                                 hashTable[elem(i,j)] = ( rowElement.distance < columnElement.distance ) ? rowElement : columnElement;
00451                         }
00452                 }
00453         }
00454         return countAdditions;
00455 }
00456 

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