Biomechanical Joint Model
 Author: Anderson Maciel

comemechatester.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 "comemechatester.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 <qlineedit.h>
00028 #include <qtabwidget.h>
00029 #include <qlabel.h>
00030 #include <qcheckbox.h>
00031 #include <qcombobox.h>
00032 #include <come_mechatestqglwidget.h>
00033 #include <dlgnewmaterial.h>
00034 #include <general/come.h>
00035 #include <general/comesimulator.h>
00036 #include <general/comescenario.h>
00037 #include <bio/comemoleculescartilage.h>
00038 #include <bio/comematerial.h>
00039 #include <algorithm>
00040 #include <qtl.h>
00041 
00042 using namespace std;
00043 
00044 COME_Mechatester::COME_Mechatester()
00045  : mechatester(){
00046  
00047         scene = new COME_Scenario();
00048         sim = new COME_Simulator();
00049         sim->setScene( scene );
00050         molecFixSelected = molecMobileSelected = NULL;
00051         //"../biomodel/models/clamp.iv" "/home/amaciel/development/biomodel/models/clamp.iv"
00052         scene->loadOrganMesh( "../biomodel/models/clamp.iv", CLAMP );
00053         scene->getPatient(0)->getOrgan(0)->setDescription( "clamp0" );
00054         scene->getPatient(0)->getOrgan(0)->scale( 0.2, 0.12, 0.01 );
00055         scene->getPatient(0)->getOrgan(0)->translate( 0.0, 0.0, 0.0 );
00056         scene->getPatient(0)->getOrgan(0)->updateSkin();
00057         scene->loadOrganMesh( "../biomodel/models/clamp.iv", CLAMP );
00058         scene->getPatient(0)->getOrgan(1)->setDescription( "clamp1" );
00059         scene->getPatient(0)->getOrgan(1)->scale( 0.2, 0.12, 0.01 );
00060         scene->getPatient(0)->getOrgan(1)->translate( 0.0, 0.0, 0.2 );
00061         scene->getPatient(0)->getOrgan(1)->updateSkin();
00062         scene->addMaterialsFromFile( "../biomodel/models/base_materials.xml", sim );
00063         openglArea->setScene( scene );
00064         openglArea->setGlobal( (COME*)this );
00065         cbMesh->setChecked( FALSE );
00066         updateMaterialsList();
00067 }
00068 
00069  void
00070  COME_Mechatester::loadFileIfArguments( int argc, char ** argv ){
00071  
00072         if( ( argc > 1 ) && ( argc < 3 ) ){
00073                 printf("Usage: mechatester [input_file] [output_file]\n" );
00074         } else if( argc == 3 ){
00075                 default_output_file = argv[2];
00076                 QString fileName = argv[1];
00077                 if( !fileName.isEmpty() ){
00078         
00079                         QString folderName = fileName;
00080                         folderName.truncate( folderName.findRev( "/" ) );
00081                         COME::baseFolder = folderName.latin1();
00082                         
00083                         QString msg = "Loading ";
00084                         statusBar()->message( msg + fileName );
00085                         hourglass(true);
00086                         scene->addOrganFromFile( fileName.latin1(), sim );
00087                         updateMaterialsList();
00088                         statusBar()->message( "Loaded.", 2000 );
00089                         hourglass(false);
00090 
00091                         // Set scene radius for view
00092                         double sceneRadius = 0.01;
00093                         COME_Point3D mins, maxs;
00094                         list<COME_BioStructure*>::const_iterator iterOrgans;
00095                         for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->begin(); iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->end(); iterOrgans++  ){
00096                                 
00097                                 ((COME_MoleculesCartilage*)(*iterOrgans))->getEnvelop( mins, maxs );
00098                                 sceneRadius = mins.vpDistance( COME_Point3D() ) > sceneRadius ? mins.vpDistance( COME_Point3D() ) : sceneRadius;
00099                                 sceneRadius = maxs.vpDistance( COME_Point3D() ) > sceneRadius ? maxs.vpDistance( COME_Point3D() ) : sceneRadius;
00100                         }
00101                         openglArea->setSceneRadius( sceneRadius + sceneRadius*0.1 );
00102                         openglArea->camera()->showEntireScene();
00103 
00104                         // Scale clampers (full of magic numbers... it's heuristical!)
00105                         scene->getPatient(0)->getOrgan("clamp0")->getEnvelop( mins, maxs );
00106                         double scaleFactor = ( sceneRadius ) / ( 2.0 * mins.vpDistance( maxs ) );
00107                         double translateZ = sceneRadius / 5.0;
00108                         scene->getPatient(0)->getOrgan("clamp0")->scale(scaleFactor,scaleFactor,scaleFactor);
00109                         scene->getPatient(0)->getOrgan("clamp1")->scale(scaleFactor,scaleFactor,scaleFactor);
00110                         scene->getPatient(0)->getOrgan("clamp1")->translate( 0.0, 0.0, translateZ );
00111 
00112                 }
00113 
00114         }
00115 
00116 }
00117 
00118 COME_Mechatester::~COME_Mechatester(){
00119 
00120         delete scene;
00121         delete sim;
00122 }
00123 
00124 void
00125 COME_Mechatester::fileOpen(){
00126 
00127         QString fileName = QFileDialog::getOpenFileName(
00128                     ".",
00129                     "Organ files (*.xml)",
00130                     this,
00131                     "open file dialog"
00132                     "Choose a file" );
00133         if( !fileName.isEmpty() ){
00134         
00135                 QString folderName = fileName;
00136                 folderName.truncate( folderName.findRev( "/" ) );
00137                 COME::baseFolder = folderName.latin1();
00138                 
00139                 QString msg = "Loading ";
00140                 statusBar()->message( msg + fileName );
00141                 hourglass(true);
00142                 scene->addOrganFromFile( fileName.latin1(), sim );
00143                 updateMaterialsList();
00144                 statusBar()->message( "Loaded.", 2000 );
00145                 hourglass(false);
00146 
00147                 // Set scene radius for view
00148                 double sceneRadius = 0.01;
00149                 COME_Point3D mins, maxs;
00150                 list<COME_BioStructure*>::const_iterator iterOrgans;
00151                 for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->begin(); iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->end(); iterOrgans++  ){
00152                         
00153                         ((COME_MoleculesCartilage*)(*iterOrgans))->getEnvelop( mins, maxs );
00154                         sceneRadius = mins.vpDistance( COME_Point3D() ) > sceneRadius ? mins.vpDistance( COME_Point3D() ) : sceneRadius;
00155                         sceneRadius = maxs.vpDistance( COME_Point3D() ) > sceneRadius ? maxs.vpDistance( COME_Point3D() ) : sceneRadius;
00156                 }
00157                 openglArea->setSceneRadius( sceneRadius + sceneRadius*0.1 );
00158                 openglArea->camera()->showEntireScene();
00159 
00160                 // Scale clampers (full of magic numbers... it's heuristical!)
00161                 scene->getPatient(0)->getOrgan("clamp0")->getEnvelop( mins, maxs );
00162                 double scaleFactor = ( sceneRadius ) / ( 2.0 * mins.vpDistance( maxs ) );
00163                 double translateZ = sceneRadius / 5.0;
00164                 scene->getPatient(0)->getOrgan("clamp0")->scale(scaleFactor,scaleFactor,scaleFactor);
00165                 scene->getPatient(0)->getOrgan("clamp1")->scale(scaleFactor,scaleFactor,scaleFactor);
00166                 scene->getPatient(0)->getOrgan("clamp1")->translate( 0.0, 0.0, translateZ );
00167 
00168         }
00169 }
00170 
00171 void
00172 COME_Mechatester::fileExportAs(){
00173 
00174         QString fileName;
00175         QFileDialog* fd = new QFileDialog( this, "save as dialog", TRUE );
00176         fd->setCaption( "Export molecules file as...");
00177         fd->setMode( QFileDialog::AnyFile );
00178         fd->setFilter( "Molecules (*.xml)" );
00179         if( default_output_file != "" )
00180                 fd->setSelection( default_output_file.c_str() );
00181         
00182         if ( fd->exec() == QDialog::Accepted ){
00183                 hourglass(true);
00184                 fileName = fd->selectedFile();
00185                 printf( "Saving %s... ", fileName.latin1() );
00186                 scene->saveFile( fileName.latin1(), sim );
00187                 printf( " saved.\n" );
00188                 hourglass(false);
00189         }
00190 }
00191 
00192 void
00193 COME_Mechatester::updateMaterialsList(){
00194         
00195         // load materials onto the list
00196         listMaterials->clear();
00197         vector<COME_Material*>* availableMaterials = scene->getAvailableMaterialsList();
00198         for( int i = 0; i < availableMaterials->size(); i++ ){
00199                 listMaterials->insertItem( QString( (*availableMaterials)[i]->getDescription().c_str() ) );
00200         }
00201         // First is selected
00202         selectedMaterial = (*availableMaterials)[0];
00203         listMaterials->setSelected( listMaterials->findItem ( (*availableMaterials)[0]->getDescription().c_str() ), true );
00204         
00205         // Load material properties onto the table.
00206         loadMaterialProperties();
00207 }
00208 
00209 void
00210 COME_Mechatester::selectMaterial(){
00211 
00212         // Set selected
00213         selectedMaterial = (*(scene->getAvailableMaterialsList()))[listMaterials->currentItem()];
00214         // Load material properties onto the table.
00215         loadMaterialProperties();
00216 }
00217 
00218 void
00219 COME_Mechatester::rotateSelected( int rx, int ry, int rz ){
00220 
00221         if( scene->getPatient(0)->getSelected() ){
00222                 double step = sbStepRotate->value() * M_PI / 180.0;
00223                 scene->getPatient(0)->getSelected()->rotate( rx*step, ry*step, rz*step );
00224                 updateClampIntersections();
00225         }
00226 }
00227 
00228 void
00229 COME_Mechatester::translateSelected( int dx, int dy, int dz ){
00230 
00231         if( scene->getPatient(0)->getSelected() ){
00232                 double step = sbStepTranslate->value() * (openglArea->sceneRadius()/(double)openglArea->width());
00233                 scene->getPatient(0)->getSelected()->translate( dx*step, dy*step, dz*step );
00234                 updateClampIntersections();
00235         }
00236 }
00237 
00238 void
00239 COME_Mechatester::scaleSelected( int fx, int fy, int fz ){
00240 
00241         if( scene->getPatient(0)->getSelected() ){
00242                 double step = ( (fx+fy+fz) > 0.0
00243                                 ? sbStepScale->value() / 100.0
00244                                 : 1.0 - (sbStepScale->value() % 100) / 100.0);
00245                 scene->getPatient(0)->getSelected()->scale( fx==0?1.0:step, fy==0?1.0:step, fz==0?1.0:step );
00246                 updateClampIntersections();
00247         }
00248 }
00249 
00250 void
00251 COME_Mechatester::loadMaterialProperties(){
00252         
00253         char chrText[20];
00254         sprintf( chrText, "%1.4f", selectedMaterial->getColor().getX() );
00255         tMaterials->setText( 0, 0, chrText ); tMaterials->setText( 0, 1, "" ); tMaterials->setText( 0, 2, "0..1" );
00256         sprintf( chrText, "%1.4f", selectedMaterial->getColor().getY() );
00257         tMaterials->setText( 1, 0, chrText ); tMaterials->setText( 1, 1, "" ); tMaterials->setText( 1, 2, "0..1" );
00258         sprintf( chrText, "%1.4f", selectedMaterial->getColor().getZ() );
00259         tMaterials->setText( 2, 0, chrText ); tMaterials->setText( 2, 1, "" ); tMaterials->setText( 2, 2, "0..1" );
00260         sprintf( chrText, "%1.4f", selectedMaterial->getDamping() );
00261         tMaterials->setText( 3, 0, chrText ); tMaterials->setText( 3, 1, "%/100" ); tMaterials->setText( 3, 2, "0..1" );
00262         sprintf( chrText, "%1.4f", selectedMaterial->getDensity() );
00263         tMaterials->setText( 4, 0, chrText ); tMaterials->setText( 4, 1, "kg/m3" ); tMaterials->setText( 4, 2, "0..~" );
00264         sprintf( chrText, "%1.10f", selectedMaterial->getPermeability() );
00265         tMaterials->setText( 5, 0, chrText ); tMaterials->setText( 5, 1, "m3/m2/s?" ); tMaterials->setText( 5, 2, "0..~" );
00266         sprintf( chrText, "%1.4f", selectedMaterial->getLiquidFraction() );
00267         tMaterials->setText( 6, 0, chrText ); tMaterials->setText( 6, 1, "%/100" ); tMaterials->setText( 6, 2, "0..1" );
00268         sprintf( chrText, "%1.4f", selectedMaterial->getMediumDensity() );
00269         tMaterials->setText( 7, 0, chrText ); tMaterials->setText( 7, 1, "kg/m3?" ); tMaterials->setText( 7, 2, "0..~" );
00270         sprintf( chrText, "%1.4f", selectedMaterial->getYoungsModulus() );
00271         tMaterials->setText( 8, 0, chrText ); tMaterials->setText( 8, 1, "N/m2" ); tMaterials->setText( 8, 2, "0..~" );
00272         sprintf( chrText, "%1.4f", selectedMaterial->getAnisotropyVector().getX() );
00273         tMaterials->setText( 10, 0, chrText ); tMaterials->setText( 10, 1, "%/100" ); tMaterials->setText( 10, 2, "0..1" );
00274         sprintf( chrText, "%1.4f", selectedMaterial->getAnisotropyVector().getY() );
00275         tMaterials->setText( 11, 0, chrText ); tMaterials->setText( 11, 1, "%/100" ); tMaterials->setText( 11, 2, "0..1" );
00276         sprintf( chrText, "%1.4f", selectedMaterial->getAnisotropyVector().getZ() );
00277         tMaterials->setText( 12, 0, chrText ); tMaterials->setText( 12, 1, "%/100" ); tMaterials->setText( 12, 2, "0..1" );
00278 }
00279 
00280 void
00281 COME_Mechatester::materialChanged( int l, int c ){
00282 
00283         
00284 
00285         selectedMaterial->setColor( COME_Vector3D( atof( tMaterials->text( 0, 0 ) ), atof( tMaterials->text( 1, 0 ) ), atof( tMaterials->text( 2, 0 ) ) ) );
00286         selectedMaterial->setDamping( atof( tMaterials->text( 3, 0 ) ) );
00287         selectedMaterial->setDensity( atof( tMaterials->text( 4, 0 ) ) );
00288         selectedMaterial->setPermeability( atof( tMaterials->text( 5, 0 ) ) );
00289         selectedMaterial->setLiquidFraction( atof( tMaterials->text( 6, 0 ) ) );
00290         selectedMaterial->setMediumDensity( atof( tMaterials->text( 7, 0 ) ) );
00291         selectedMaterial->setYoungsModulus( atof( tMaterials->text( 8, 0 ) ) );
00292         selectedMaterial->setAnisotropyVector( COME_Vector3D( atof( tMaterials->text( 10, 0 ) ), atof( tMaterials->text( 11, 0 ) ), atof( tMaterials->text( 12, 0 ) ) ) );
00293                 
00294         char chrText[40];
00295         sprintf( chrText, "Material changed at line: %d column: %d", l, c );
00296         QString msg = chrText;
00297         statusBar()->message( msg, 1000 );
00298 }
00299 
00300 void
00301 COME_Mechatester::clickedNewMaterial(){
00302 
00303         dlgNewMaterial* dlg = new dlgNewMaterial( this );
00304         
00305         if ( dlg->exec() == QDialog::Accepted ){
00306         
00307                 COME_Material *newMaterial = new COME_Material();
00308                 newMaterial->setDescription( dlg->newDescription->text().latin1() );
00309                 scene->getAvailableMaterialsList()->push_back( newMaterial );
00310                 updateMaterialsList();
00311         }
00312         delete dlg;
00313 }
00314 
00315 void
00316 COME_Mechatester::clickedDelMaterial(){
00317 
00318         vector<COME_Material*>::iterator select_iter;
00319         for( select_iter = scene->getAvailableMaterialsList()->begin(); select_iter != scene->getAvailableMaterialsList()->end(); select_iter++ ){
00320                 if( (*select_iter)->getDescription() == selectedMaterial->getDescription() )
00321                         break;
00322         }
00323         if( select_iter != scene->getAvailableMaterialsList()->end() ){
00324                 scene->getAvailableMaterialsList()->erase( select_iter );
00325                 updateMaterialsList();
00326         }
00327 }
00328 
00329 void
00330 COME_Mechatester::clickedAssociate(){
00331 
00332         if( scene->getPatient(0)->getSelected() ){
00333                 char chrText[100];
00334                 sprintf( chrText, "Material %s is now associated to object %s.", selectedMaterial->getDescription().c_str(), scene->getPatient(0)->getSelected()->getDescription().c_str() );
00335                 QString msg = chrText;
00336                 statusBar()->message( msg, 2000 );
00337                 scene->getPatient(0)->getSelected()->getTissue()->setMoleculesMaterial( selectedMaterial );
00338         } else {
00339                 statusBar()->message( "No association created because there is no object selected.", 2000 );
00340         }
00341 }
00342 void
00343 COME_Mechatester::clickedCheck(){
00344 
00345         list<COME_BioStructure*>::const_iterator iterOrgans;
00346         for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->begin(), iterOrgans++, iterOrgans++; iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->end(); iterOrgans++  ){
00347         
00348                 ((COME_MoleculesCartilage*)(*iterOrgans))->getTissue()->checkInitialPositions();
00349                 ((COME_MoleculesCartilage*)(*iterOrgans))->getTissue()->makeAllLocalFrames();
00350                 ((COME_MoleculesCartilage*)(*iterOrgans))->updateSkin();
00351                 updateClampIntersections();
00352         }
00353 }
00354 
00355 void
00356 COME_Mechatester::clickedReset(){
00357 
00358         list<COME_BioStructure*>::const_iterator iterOrgans;
00359         for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->begin(), iterOrgans++, iterOrgans++; iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->end(); iterOrgans++  ){
00360         
00361                 ((COME_MoleculesCartilage*)(*iterOrgans))->getTissue()->resetInitialPositions();
00362                 ((COME_MoleculesCartilage*)(*iterOrgans))->getTissue()->makeAllLocalFrames();
00363                 ((COME_MoleculesCartilage*)(*iterOrgans))->updateSkin();
00364                 updateClampIntersections();
00365         }
00366 }
00367 
00368 void
00369 COME_Mechatester::clickedStartSim(){
00370 
00371         char chrText[20];
00372         
00373         if( cbConfigure->isChecked() ){
00374 
00375                 // initialize molec config TEMPORARY
00376                 if( scene->getPatient(0)->getOrgan(2)->getGlobalHooke() == 0.0 ){
00377                         scene->getPatient(0)->getOrgan(2)->setGlobalHooke( scene->getPatient(0)->getOrgan(2)->getTissue()->getShape()->front()->getConnectionList()->front()->getHookeConst() );
00378                 }
00379         }
00380         
00381         if( tabSimulation->currentPageIndex() == 0 ){
00382         
00383                 // Simulate by forces
00384                 sim->setDuration( atof(leFadeInForce->text()) + atof(leKeepForce->text()) + atof(leFadeOutForce->text()) );
00385                 pressureArea = 0.0;
00386                 
00387                 // Set forces
00388                 list<COME_BioStructure*>::const_iterator iterOrgans;
00389                 for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->begin(), iterOrgans++, iterOrgans++; iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->end(); iterOrgans++  ){
00390                 
00391                         list<COME_Molecule*>* molecules = ((COME_MoleculesCartilage*)(*iterOrgans))->getTissue()->getShape();
00392                         list<COME_Molecule*>::iterator iterMolecules;
00393                         double totalMolecForce = 0.0;
00394                         for ( iterMolecules = molecules->begin(); iterMolecules != molecules->end(); iterMolecules++){
00395                                 if( (*iterMolecules)->intersectClampMobile() ){
00396                                         totalMolecForce+=1.0;
00397                                         pressureArea+=(*iterMolecules)->getPressureArea();
00398                                         // just choose one
00399                                         molecMobileSelected = (*iterMolecules);
00400                                 }
00401                                 (*iterMolecules)->clearExternalForces();
00402                         }
00403                         double xSplitForce = atof(leForceX->text())/totalMolecForce;
00404                         double ySplitForce = atof(leForceY->text())/totalMolecForce;
00405                         double zSplitForce = atof(leForceZ->text())/totalMolecForce;
00406                         double currDistance = INFINITE;
00407                         for ( iterMolecules = molecules->begin(); iterMolecules != molecules->end(); iterMolecules++){
00408                         
00409                                 (*iterMolecules)->setFixed( false );
00410                                 if( (*iterMolecules)->intersectClampMobile() ){
00411                                         COME_TimeForce *forceIn = new COME_TimeForce( xSplitForce, ySplitForce, zSplitForce, atof(leFadeInForce->text()) );
00412                                         COME_TimeForce *forceKeep = new COME_TimeForce( xSplitForce, ySplitForce, zSplitForce, atof(leFadeInForce->text()) + atof(leKeepForce->text()) );
00413                                         COME_TimeForce *forceOut = new COME_TimeForce( 0.0, 0.0, 0.0, atof(leFadeInForce->text()) + atof(leKeepForce->text()) + atof(leFadeOutForce->text()) );
00414                                         
00415                                         (*iterMolecules)->addExternalForce( new COME_TimeForce( 0.0, 0.0, 0.0, 0.0 ) );
00416                                         (*iterMolecules)->addExternalForce( forceIn );
00417                                         (*iterMolecules)->addExternalForce( forceKeep );
00418                                         (*iterMolecules)->addExternalForce( forceOut );
00419                                 } else if( (*iterMolecules)->intersectClampFix() ) {
00420                                         (*iterMolecules)->setFixed( true );
00421                                         // take the closest as fixed selected
00422                                         if( molecMobileSelected )
00423                                         if( (*iterMolecules)->getPosition().vpDistance( molecMobileSelected->getPosition() ) < currDistance ){
00424                                                 molecFixSelected = (*iterMolecules);
00425                                                 currDistance = (*iterMolecules)->getPosition().vpDistance( molecMobileSelected->getPosition() );
00426                                         }
00427                                 }
00428                         }
00429                 }
00430                 if( molecFixSelected && molecMobileSelected )
00431                         previousLenght = initialLength = molecFixSelected->getPosition().vpDistance( molecMobileSelected->getPosition() );
00432         } else {
00433                 // Simulate by displacement
00434                 sim->setDuration( atof(leFadeInDisp->text()) + atof(leKeepDisp->text()) + atof(leFadeOutDisp->text()) );
00435         
00436         }
00437         
00438         // Simulate physics here to perform the test
00439         sim->setFPS( sbFPS->value() );
00440         sim->start();
00441 
00442 }
00443 
00444 void
00445 COME_Mechatester::updateClampIntersections(){
00446 
00447         if( !sim->isRunning() ){
00448         
00449                 // test intersections
00450                 COME_Mesh* clamp0 = scene->getPatient(0)->getOrgan(0)->getSurface();
00451                 COME_Mesh* clamp1 = scene->getPatient(0)->getOrgan(1)->getSurface();
00452                 list<COME_BioStructure*>::const_iterator iterOrgans;
00453                 for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->begin(), iterOrgans++, iterOrgans++; iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->end(); iterOrgans++  ){
00454                 
00455                         list<COME_Molecule*>* molecules = ((COME_MoleculesCartilage*)(*iterOrgans))->getTissue()->getShape();
00456                         list<COME_Molecule*>::iterator iterMolecules;
00457                         for ( iterMolecules = molecules->begin(); iterMolecules != molecules->end(); iterMolecules++){
00458                         
00459                                 if( clamp0->isInside( (*iterMolecules)->getPosition() ) ){
00460                                         (*iterMolecules)->setIntersectClamp( CLAMPFIX );
00461                                 } else if ( clamp1->isInside( (*iterMolecules)->getPosition() ) ){
00462                                         (*iterMolecules)->setIntersectClamp( CLAMPMOBILE );
00463                                 } else {
00464                                         (*iterMolecules)->setIntersectClamp( FREE );
00465                                 }
00466                         }
00467                 }
00468                 
00469         }
00470 }
00471 
00472 void
00473 COME_Mechatester::updateEquation(){
00474 
00475         char chrText[20];
00476         double momentaryElasticity;
00477         
00478         if( molecFixSelected && molecMobileSelected ){
00479                 COME_Vector3D force(atof(leForceX->text()), atof(leForceY->text()), atof(leForceZ->text()));
00480                 sprintf( chrText, "%3.4f x %2.4f", force.vpModule(), initialLength );
00481                 tlNumerator->setText( chrText );
00482                 
00483                 double currentLength = molecFixSelected->getPosition().vpDistance( molecMobileSelected->getPosition() );
00484                 sprintf( chrText, "%1.5f x %2.5f", currentLength - initialLength, pressureArea );
00485                 tlDenominator->setText( chrText );
00486                 momentaryElasticity = ( force.vpModule() * initialLength ) / ( fabs(currentLength - initialLength) * pressureArea );
00487                 sprintf( chrText, "%6.1f", momentaryElasticity );
00488                 tlElasticity->setText( chrText );
00489         
00490                 if( cbConfigure->isChecked() ){
00491         
00492                         double increment = 1.0;
00493                         /*// recalculate hooks
00494                         double targetDistance = initialLength + ( ( force.vpModule() * initialLength ) / ( selectedMaterial->getYoungsModulus() * pressureArea ) );
00495                         if( targetDistance > currentLength ){
00496                                 if(( previousLenght >= currentLength ) ){
00497                                         increment = 1.0 - fabs( fabs(targetDistance) - fabs(currentLength))*atof( lePrecision->text() );
00498                                         printf("inc: %f ", increment );
00499                                 }
00500                         } else if( targetDistance < currentLength ){
00501                                 if( ( previousLenght >= currentLength ) ){
00502                                         increment = 1.0 + fabs( fabs(targetDistance) - fabs(currentLength))*atof( lePrecision->text() );
00503                                         printf("inc: %f ", increment );
00504                                 }
00505                         }*/
00506                         
00507                         double targetDistance = initialLength + ( ( force.vpModule() * initialLength ) / ( selectedMaterial->getYoungsModulus() * pressureArea ) );
00508                         if( fabs( targetDistance - previousLenght ) < fabs( targetDistance - currentLength ) ){ // if NOT approaching
00509                         
00510                                 COME_Vector3D direction( molecMobileSelected->getPosition() - molecFixSelected->getPosition() );
00511                                 if( ( force.vpDotProduct( direction ) / ( force.vpModule() * direction.vpModule() ) ) >= 0.0 ){ // if force is tensioning
00512                                 
00513                                         if( targetDistance < currentLength ){ // bigger
00514                                                 increment = 1.0 + fabs( fabs(targetDistance) - fabs(currentLength))*atof( lePrecision->text() );
00515                                         } else { // smaller
00516                                                 increment = 1.0 - fabs( fabs(targetDistance) - fabs(currentLength))*atof( lePrecision->text() );
00517                                         }
00518                                 
00519                                 } else { // if force is compressing
00520                                 
00521                                         if( targetDistance < currentLength ){ // bigger
00522                                                 increment = 1.0 - fabs( fabs(targetDistance) - fabs(currentLength))*atof( lePrecision->text() );
00523                                         } else { // smaller
00524                                                 increment = 1.0 + fabs( fabs(targetDistance) - fabs(currentLength))*atof( lePrecision->text() );
00525                                         }
00526                                 
00527                                 }
00528                         }
00529                         
00530                         previousLenght = currentLength;
00531         
00532                         list<COME_BioStructure*>::const_iterator iterOrgans;
00533                         for( iterOrgans = ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->begin(), iterOrgans++, iterOrgans++; iterOrgans != ((list<COME_BioStructure *>*)scene->getPatient(0)->getPtOrganList())->end(); iterOrgans++  ){
00534                         
00535                                 double newGlobalHooke = ((COME_MoleculesCartilage*)(*iterOrgans))->getGlobalHooke() * increment;
00536                                 ((COME_MoleculesCartilage*)(*iterOrgans))->setGlobalHooke( newGlobalHooke );
00537                                 COME_Vector3D aniso = selectedMaterial->getAnisotropyVector();
00538                         
00539                                 list<COME_Molecule*>* molecules = ((COME_MoleculesCartilage*)(*iterOrgans))->getTissue()->getShape();
00540                                 list<COME_Molecule*>::iterator iterMolecules;
00541                                 for ( iterMolecules = molecules->begin(); iterMolecules != molecules->end(); iterMolecules++){
00542         
00543                                         list<COME_MoleculeLink*>::iterator iterLink;
00544                                         for (iterLink = (*iterMolecules)->getConnectionList()->begin(); iterLink != (*iterMolecules)->getConnectionList()->end(); iterLink++ ){
00545                                                 COME_Vector3D kVec = (*iterLink)->getElement(0)->getPosition() - (*iterLink)->getElement(1)->getPosition();
00546                                                 kVec.vpNormalize();
00547                                                 double kThisLink = ( ( fabs(kVec.getX()) * aniso.getX() ) + ( fabs(kVec.getY()) * aniso.getY() ) + ( fabs(kVec.getZ()) * aniso.getZ() ) )* newGlobalHooke;
00548                                                 (*iterLink)->setHookeConst( kThisLink );
00549                                         }
00550                                 }
00551                         }       
00552                 }
00553         }
00554 }
00555 
00556 void
00557 COME_Mechatester::changedNumIntegration(){
00558 
00559         char chrType[60];
00560         switch( cbNumIntegration->currentItem() ){
00561                 case 0: COME::flagNumIntegration = EULER; strcpy(chrType,"Numerical integration method is now Euler.");break;
00562                 case 1: COME::flagNumIntegration = RUNGE_KUTTA4; strcpy(chrType,"Numerical integration method is now Runge-Kutta 4."); break;
00563         }
00564         QString msg = chrType;
00565         statusBar()->message( msg, 2000 );
00566 }
00567 
00568 void
00569 COME_Mechatester::hourglass( bool yesno ){
00570 
00571         if( yesno ){
00572                 setCursor( Qt::WaitCursor );
00573                 openglArea->setCursor( Qt::WaitCursor );
00574         } else {
00575                 setCursor( Qt::ArrowCursor );
00576                 openglArea->setCursor( Qt::ArrowCursor );
00577         }
00578 }

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