Biomechanical Joint Model
 Author: Anderson Maciel

comemodeljoint.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004 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  **************************************************************************/
00020 #include "comemodeljoint.h"
00021 #include <qfiledialog.h>
00022 #include <qspinbox.h>
00023 #include <qcursor.h>
00024 #include <qstatusbar.h>
00025 #include <qtable.h>
00026 #include <qlistbox.h>
00027 #include <qcombobox.h>
00028 #include <qlineedit.h>
00029 #include <qtabwidget.h>
00030 #include <qlabel.h>
00031 #include <qcheckbox.h>
00032 #include <qslider.h>
00033 #include <qpushbutton.h>
00034 #include <come_modeljointqglwidget.h>
00035 #include <dlgnewmaterial.h>
00036 #include <general/come.h>
00037 #include <general/comesimulator.h>
00038 #include <general/comescenario.h>
00039 //#include <general/comexml.h>
00040 #include <bio/comemoleculescartilage.h>
00041 #include <bio/comematerial.h>
00042 #include <physics/comecollide.h>
00043 #include <algorithm>
00044 #include <qtl.h>
00045 
00046 using namespace std;
00047 
00048 COME_ModelJoint::COME_ModelJoint()
00049  : modeljoint(){
00050  
00051         scene = new COME_Scenario();
00052         sim = new COME_Simulator();
00053         sim->setScene( scene );
00054         molecFixSelected = molecMobileSelected = NULL;
00055         
00056         openglArea->setScene( scene );
00057         openglArea->setGlobal( (COME*)this );
00058 }
00059 
00060 
00061 COME_ModelJoint::~COME_ModelJoint(){
00062 
00063         delete scene;
00064         delete sim;
00065 }
00066 
00067 void
00068 COME_ModelJoint::fileOpen(){
00069 /*
00070         QString fileName = QFileDialog::getOpenFileName(
00071                     ".",
00072                     "Organ files (*.xml)",
00073                     this,
00074                     "open file dialog"
00075                     "Choose a file" );
00076         if( !fileName.isEmpty() ){
00077         
00078                 QString folderName = fileName;
00079                 folderName.truncate( folderName.findRev( "/" ) );
00080                 COME::baseFolder = folderName.latin1();
00081         
00082                 QString msg = "Loading ";
00083                 statusBar()->message( msg + fileName );
00084                 hourglass(true);
00085                 scene->addOrganFromFile( fileName.latin1(), sim );
00086                 openglArea->loadTextures();
00087                 statusBar()->message( "Loaded.", 2000 );
00088                 hourglass(false);
00089         }
00090 */
00091         fileLoad_scene();
00092 }
00093 
00094 void
00095  COME_ModelJoint::loadFileIfArguments( int argc, char ** argv ){
00096  
00097         if( ( argc > 1 ) && ( argc < 3 ) ){
00098                 printf("Usage: modeljoint [input_file] [output_file]\n" );
00099         } else if( argc == 3 ){
00100                 default_output_file = argv[2];
00101                 QString fileName = argv[1];
00102                 if( !fileName.isEmpty() ){
00103 
00104                         QString folderName = fileName;
00105                         folderName.truncate( folderName.findRev( "/" ) );
00106                         COME::baseFolder = folderName.latin1();
00107                         
00108                         QString msg = "Loading scene from ";
00109                         statusBar()->message( msg + fileName );
00110                         hourglass(true);
00111                         scene->loadFile( fileName.latin1(), sim );
00112                         scene->setDescription( fileName.latin1() );
00113                         statusBar()->message( "Loaded.", 2000 );
00114                         openglArea->loadTextures();
00115                         
00116                         // Set scene radius for view
00117                         double sceneRadius = 0.01;
00118                         COME_Point3D mins, maxs;
00119                         for( int iP = 0; iP < scene->getPatientList()->size(); iP++ ){
00120                         list<COME_BioStructure*>::const_iterator iterOrgans;
00121                                 for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(iP)->getPtOrganList())->begin(); iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(iP)->getPtOrganList())->end(); iterOrgans++  ){
00122                                         
00123                                         if( (*iterOrgans)->getSurface() ){
00124                                                 (*iterOrgans)->getSurface()->getEnvelop( mins, maxs );
00125                                                 sceneRadius = fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00126                                                 sceneRadius = fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00127                                         }
00128                                         (*iterOrgans)->getEnvelop( mins, maxs );
00129                                         sceneRadius = fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00130                                         sceneRadius = fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00131                                 }
00132                         }
00133                         openglArea->setSceneRadius( sceneRadius + sceneRadius*0.1 );
00134                         openglArea->camera()->showEntireScene();
00135                         
00136                         if( COME::flagCollisionTreatment == NEIGHBORS ){
00137                                 scene->getCollisionDetector()->initializeProximityStructure();
00138                         }
00139                         
00140                         hourglass(false);
00141                 }
00142 
00143         }
00144 
00145  }
00146 
00147 void
00148 COME_ModelJoint::fileLoad_scene(){
00149 
00150         QString fileName = QFileDialog::getOpenFileName(
00151                     ".",
00152                     "Scene files (*.xml)",
00153                     this,
00154                     "open file dialog"
00155                     "Choose a file" );
00156         if( !fileName.isEmpty() ){
00157         
00158                 QString folderName = fileName;
00159                 folderName.truncate( folderName.findRev( "/" ) );
00160                 COME::baseFolder = folderName.latin1();
00161                 
00162                 QString msg = "Loading scene from ";
00163                 statusBar()->message( msg + fileName );
00164                 hourglass(true);
00165                 scene->loadFile( fileName.latin1(), sim );
00166                 scene->setDescription( fileName.latin1() );
00167                 statusBar()->message( "Loaded.", 2000 );
00168                 openglArea->loadTextures();
00169                 
00170                 // Set scene radius for view
00171                 double sceneRadius = 0.01;
00172                 COME_Point3D mins, maxs;
00173                 for( int iP = 0; iP < scene->getPatientList()->size(); iP++ ){
00174                 list<COME_BioStructure*>::const_iterator iterOrgans;
00175                         for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(iP)->getPtOrganList())->begin(); iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(iP)->getPtOrganList())->end(); iterOrgans++  ){
00176                                 
00177                                 if( (*iterOrgans)->getSurface() ){
00178                                         (*iterOrgans)->getSurface()->getEnvelop( mins, maxs );
00179                                         sceneRadius = fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00180                                         sceneRadius = fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00181                                 }
00182                                 (*iterOrgans)->getEnvelop( mins, maxs );
00183                                 sceneRadius = fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( mins.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00184                                 sceneRadius = fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) > sceneRadius ? fabs( maxs.vpDistance( COME_Point3D(0,0,0) ) ) : sceneRadius;
00185                         }
00186                 }
00187                 openglArea->setSceneRadius( sceneRadius + sceneRadius*0.1 );
00188                 openglArea->camera()->showEntireScene();
00189                 
00190                 if( COME::flagCollisionTreatment == NEIGHBORS ){
00191                         scene->getCollisionDetector()->initializeProximityStructure();
00192                 }
00193                 
00194                 hourglass(false);
00195         }
00196 }
00197 
00198 
00199 void
00200 COME_ModelJoint::fileExportAs(){
00201 
00202         QString fileName;
00203         QFileDialog* fd = new QFileDialog( this, "save as dialog", TRUE );
00204         fd->setCaption( "Export molecules file as...");
00205         fd->setMode( QFileDialog::AnyFile );
00206         fd->setFilter( "Molecules (*.xml)" );
00207         if( default_output_file != "" )
00208                 fd->setSelection( default_output_file.c_str() );
00209         
00210         if ( fd->exec() == QDialog::Accepted ){
00211                 hourglass(true);
00212                 fileName = fd->selectedFile();
00213                 printf( "Saving %s... ", fileName.latin1() );
00214                 scene->saveFile( fileName.latin1(), sim );
00215                 printf( " saved.\n" );
00216                 hourglass(false);
00217         }
00218 }
00219 
00220 void
00221 COME_ModelJoint::rotateSelected( int rx, int ry, int rz ){
00222 
00223         if( scene->getPatient(0)->getSelected() ){
00224                 double step = sbStepRotate->value() * M_PI / 180.0;
00225                 scene->getPatient(0)->getSelected()->rotate( rx*step, ry*step, rz*step );
00226         }
00227 }
00228 
00229 void
00230 COME_ModelJoint::translateSelected( int dx, int dy, int dz ){
00231 
00232         if( scene->getPatient(0)->getSelected() ){
00233                 double step = sbStepTranslate->value() * (openglArea->sceneRadius()/(double)openglArea->width());
00234                 scene->getPatient(0)->getSelected()->translate( dx*step, dy*step, dz*step );
00235                 //printf(" %f %f %f \n", dx*step, dy*step, dz*step );
00236         }
00237 }
00238 
00239 void
00240 COME_ModelJoint::scaleSelected( int fx, int fy, int fz ){
00241 
00242         if( scene->getPatient(0)->getSelected() ){
00243                 double step = ( (fx+fy+fz) > 0.0
00244                                 ? sbStepScale->value() / 100.0
00245                                 : 1.0 - (sbStepScale->value() % 100) / 100.0);
00246                 scene->getPatient(0)->getSelected()->scale( fx==0?1.0:step, fy==0?1.0:step, fz==0?1.0:step );
00247         }
00248 }
00249 
00250 void
00251 COME_ModelJoint::clickedStartSim(){
00252 
00253         // Simulate physics here to perform the test
00254         sim->setDuration( atof(leFadeInForce->text()) + atof(leKeepForce->text()) + atof(leFadeOutForce->text()) );
00255         sim->setFPS( sbFPS->value() );
00256         bpStartForce->setDown( true );
00257         sim->start();
00258 
00259 }
00260 
00261 void
00262 COME_ModelJoint::pauseSim(){
00263 
00264         // Pause simulation
00265         if( !sim->getPause() ){
00266                 pbPause->setDown( true );
00267                 sim->setPause( true );
00268         } else {
00269                 pbPause->setDown( false );
00270                 sim->setPause( false );
00271         }
00272 }
00273 
00274 void
00275 COME_ModelJoint::fpsChange(){
00276 
00277         char chrStr[10];
00278         sprintf( chrStr, "%1.6f", 1.0/(double)sbFPS->value() );
00279         leTimeStep->setText( chrStr );
00280         sim->setDuration( atof(leFadeInForce->text()) + atof(leKeepForce->text()) + atof(leFadeOutForce->text()) );
00281         sim->setFPS( sbFPS->value() );
00282 }
00283 
00284 void
00285 COME_ModelJoint::durationChange(){
00286         
00287         sim->setDuration( atof(leFadeInForce->text()) + atof(leKeepForce->text()) + atof(leFadeOutForce->text()) );
00288 }
00289 
00290 void
00291 COME_ModelJoint::changedCollisionTreatment(){
00292 
00293         char chrType[100];
00294         switch( cbCollisionTreatment->currentItem() ){
00295                 case 0: COME::flagCollisionTreatment = SPHERES; strcpy(chrType,"Collision treatment is now set to use SPHERES.");break;
00296                 case 1: COME::flagCollisionTreatment = MESH; strcpy(chrType,"Collision treatment is now set to use MESHES."); break;
00297                 case 2: COME::flagCollisionTreatment = HYBRID; strcpy(chrType,"Collision treatment is now set to use MESHES for detection and SPHERES for force calculation."); break;
00298                 case 3: COME::flagCollisionTreatment = DISPLACEMENT; strcpy(chrType,"Collision treatment is now set to displacement fields."); break;
00299                 case 4: COME::flagCollisionTreatment = NO_COLLISION; strcpy(chrType,"No collision treatment."); break;
00300                 case 5: COME::flagCollisionTreatment = NEIGHBORS; scene->getCollisionDetector()->initializeProximityStructure(); strcpy(chrType,"Using neighbors and prediction for collision treatment."); break;
00301                 case 6: COME::flagCollisionTreatment = SPHERICAL_SLIDING; scene->initializeAllHashs(); strcpy(chrType,"Using spherical sliding for collision treatment."); break;
00302         }
00303         QString msg = chrType;
00304         statusBar()->message( msg, 2000 );
00305 }
00306 
00307 void
00308 COME_ModelJoint::changed2ndPass(){
00309 
00310         char chrType[100];
00311 
00312         COME::flagCollision2ndPass = cb2ndPass->isChecked();
00313         strcpy(chrType,"Apply checking vertices near to collisions for completely immerged faces.");
00314         QString msg = chrType;
00315         statusBar()->message( msg, 2000 );
00316 }
00317 
00318 void
00319 COME_ModelJoint::changedNumIntegration(){
00320 
00321         char chrType[60];
00322         switch( cbNumIntegration->currentItem() ){
00323                 case 0: COME::flagNumIntegration = EULER; strcpy(chrType,"Numerical integration method is now Euler.");break;
00324                 case 1: COME::flagNumIntegration = RUNGE_KUTTA4; strcpy(chrType,"Numerical integration method is now Runge-Kutta 4."); break;
00325         }
00326         QString msg = chrType;
00327         statusBar()->message( msg, 2000 );
00328 }
00329 
00330 void
00331 COME_ModelJoint::exportPrecalculationChanged(){
00332 
00333         COME::flagExportToPrecalculatedFile = cbExportPrecalculation->isChecked();
00334         
00335         if( COME::flagExportToPrecalculatedFile ){
00336         
00337                 tlAnimationResolution->setEnabled(true);
00338                 leAnimationResolution->setEnabled(true);
00339                 
00340                 if( atof( leTimeStep->text() ) < atof( leAnimationResolution->text() ) ){
00341                         leAnimationResolution->setText( leTimeStep->text() );
00342                         animationResolutionChanged();
00343                 }
00344                 
00345                 // for all deformable
00346                 scene->createPrecalculatedFiles();
00347                 
00348                 // this must be used by the player application
00349                 //((COME_MoleculesCartilage*)tempOrgan)->getTissue()->loadDeformationFile( fileDeformation );
00350                         
00351                 sim->setType( OFFLINE );
00352                 
00353                 // this must be used by the player application
00354                 //simulator->setType( ONLINE );
00355         } else {
00356                 tlAnimationResolution->setEnabled(false);
00357                 leAnimationResolution->setEnabled(false);
00358         }
00359 }
00360 
00361 void
00362 COME_ModelJoint::animationResolutionChanged(){
00363 
00364         COME::flagAnimationResolution = atof( leAnimationResolution->text() );
00365 }
00366 
00367 void
00368 COME_ModelJoint::sliderNominalReleased(){
00369 
00370         char chrType[60];
00371         
00372         if( scene->getPatient(0)->getSelected() ){
00373                 
00374                 scene->getPatient(0)->getSelected()->scaleNominals( 1.0 - ( ((float)(sliderNominal->value())) / 100.0 ) );
00375         }
00376         
00377         strcpy(chrType,"Nominal distances changed for the selected object.");
00378         QString msg = chrType;
00379         statusBar()->message( msg, 2000 );
00380 }
00381 
00382 void
00383 COME_ModelJoint::hourglass( bool yesno ){
00384 
00385         if( yesno ){
00386                 setCursor( Qt::WaitCursor );
00387                 openglArea->setCursor( Qt::WaitCursor );
00388         } else {
00389                 setCursor( Qt::ArrowCursor );
00390                 openglArea->setCursor( Qt::ArrowCursor );
00391         }
00392 }

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