RealGUI_record.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This program is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU General Public License as published by the Free  *
00007 * Software Foundation; either version 2 of the License, or (at your option)   *
00008 * any later version.                                                          *
00009 *                                                                             *
00010 * This program is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
00013 * more details.                                                               *
00014 *                                                                             *
00015 * You should have received a copy of the GNU General Public License along     *
00016 * with this program; if not, write to the Free Software Foundation, Inc., 51  *
00017 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
00018 *******************************************************************************
00019 *                            SOFA :: Applications                             *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 #include <sofa/gui/qt/RealGUI.h>
00028 
00029 #ifdef SOFA_GUI_QTOGREVIEWER 
00030 #include "viewer/qtogre/QtOgreViewer.h"
00031 #endif
00032 
00033 #ifdef SOFA_GUI_QTVIEWER
00034 #include "viewer/qt/QtViewer.h"
00035 #endif
00036 
00037 #ifdef SOFA_GUI_QGLVIEWER
00038 #include "viewer/qgl/QtGLViewer.h"
00039 #endif
00040 
00041 
00042 #include <sofa/simulation/tree/Simulation.h>
00043 
00044 #include <sofa/simulation/common/VisualVisitor.h>
00045 #include <sofa/simulation/common/InitVisitor.h>
00046 #include <sofa/simulation/common/WriteStateVisitor.h>
00047 #include <sofa/simulation/common/UpdateContextVisitor.h>
00048 
00049 #include <sofa/component/misc/ReadState.h>
00050 #include <sofa/component/misc/WriteState.h>
00051 
00052 #include <sofa/helper/system/SetDirectory.h>
00053 #include <sofa/helper/system/FileRepository.h>
00054 
00055 
00056 #ifdef SOFA_QT4
00057 #include <QInputDialog>
00058 #else
00059 #include <qinputdialog.h>
00060 #endif
00061 
00062 
00063 
00064 
00065 namespace sofa
00066 {
00067 
00068   namespace gui
00069   {
00070 
00071     namespace qt
00072     {
00073 
00074 
00075       using sofa::core::objectmodel::BaseObject;
00076 
00077       using namespace sofa::simulation::tree;
00078       
00079       void RealGUI::clearRecord()
00080       {         
00081     timeSlider->setValue(0);    
00082     timeSlider->setMinValue(0);
00083     timeSlider->setMaxValue(0);     
00084     setRecordInitialTime(initial_time);
00085     setRecordFinalTime(initial_time);
00086     setRecordTime(initial_time);            
00087     viewer->getScene()->execute< sofa::simulation::UpdateSimulationContextVisitor >();
00088     timeSlider->update();
00089       }
00090       
00091       bool RealGUI::setWriteSceneName()
00092       {   
00093     bool ok;
00094     QString text = QInputDialog::getText("Record Simulation", "Enter the name of your simulation:", QLineEdit::Normal,
00095                          QString::null, &ok, this );
00096     if (!ok){return false;}
00097     if ( !text.isEmpty() ) {        
00098       std::string dir = sofa::helper::system::SetDirectory::GetParentDir(viewer->getSceneFileName().c_str()) ;
00099       if (dir == "") dir = ".";
00100       simulation_name = dir + "/" + text.ascii();
00101       writeSceneName  = record_directory +  text.ascii();
00102     } else {
00103       //Create the filename to use, to save the mechanical states
00104       writeSceneName = record_directory+sofa::helper::system::SetDirectory::GetFileName(simulation_name.c_str());
00105         std::string::size_type pos = writeSceneName.rfind('.');
00106         if (pos != std::string::npos) writeSceneName.resize(pos);
00107     }
00108     return true;
00109       }
00110 
00111       void RealGUI::addReadState(bool init)
00112       {     
00113     sofa::component::misc::ReadStateCreator v(writeSceneName,init);
00114     v.execute(viewer->getScene());  
00115     std::cout << "Reading Recorded simulation with base name: " << writeSceneName << "\n";
00116       }
00117       
00118       void RealGUI::addWriteState()
00119       { 
00120     sofa::component::misc::WriteStateCreator v(writeSceneName);
00121     v.execute(viewer->getScene());  
00122     std::cout << "Recording simulation with base name: " << writeSceneName << "\n";
00123       }
00124 
00125       
00126       void RealGUI::slot_backward(  )
00127       {
00128     if (timeSlider->value() != timeSlider->minValue())
00129     {
00130       setRecordTime(getRecordInitialTime());
00131       slot_sliderValue(timeSlider->minValue());
00132       loadSimulation();
00133     }
00134       }
00135 
00136 
00137       //-----------------------------------------------------------------------------------
00138       //Recording a simulation
00139       void RealGUI::slot_recordSimulation( bool value)
00140       {
00141     if (value) 
00142     {
00143       Node* groot = getScene();
00144       if (groot)
00145       { 
00146          
00147         if (setWriteSceneName())
00148         {
00149           clearRecord();
00150           std::string filename = viewer->getSceneFileName();
00151         //Add if needed WriteState
00152         addWriteState();
00153         addReadState(false); //no init done     
00154         record_simulation=true; 
00155         playpauseGUI(true);
00156           }
00157         else  { record->setOn ( false );return;}
00158       }
00159     }
00160     else 
00161     {
00162       record_simulation=false;
00163       playpauseGUI(false);
00164         //Save simulation file
00165 
00166       std::string filename = viewer->getSceneFileName();
00167       filename = sofa::helper::system::SetDirectory::GetFileName(filename.c_str());
00168       std::string simulationFileName = simulation_name + ".simu";
00169 
00170       std::string output(record_directory + filename);
00171                 
00172       std::ofstream out(simulationFileName.c_str());
00173       if (!out.fail())
00174       {
00175         out << sofa::helper::system::DataRepository.getFile ( viewer->getSceneFileName() ) << " " << initialTime->text().ascii() << " " << finalTime->text().ascii() << " " << dtEdit->text().ascii() << " baseName: "<<writeSceneName;
00176         out.close();
00177       }
00178       std::cout << "Simulation parameters saved in "<<simulationFileName<<std::endl;
00179     }
00180       //Change the state of the writers
00181     sofa::component::misc::WriteStateActivator v_write(value);
00182     v_write.execute(viewer->getScene());    
00183     sofa::component::misc::ReadStateActivator v_read(false);
00184     v_read.execute(viewer->getScene());   
00185       }
00186       
00187       void RealGUI::slot_stepbackward()
00188       {
00189     playforward_record->setOn(false);
00190     
00191     double init_time  = getRecordInitialTime();
00192     double time = getRecordTime() - atof(dtEdit->text());
00193     if (time >= init_time)
00194     {
00195       setRecordTime(time);
00196       slot_loadrecord_timevalue();
00197     }
00198       }
00199 
00200 
00201       void RealGUI::slot_playforward( )
00202       {     
00203     if (playforward_record->isOn() ) 
00204     {
00205       if (timeSlider->value() == timeSlider->maxValue())
00206       {
00207         playforward_record->setOn(false);
00208       }
00209       else
00210       {
00211         loadSimulation();
00212         setPixmap("textures/media-playback-pause.png", playforward_record);
00213         
00214         timerRecordStep->start ( 0 );
00215       }
00216     }     
00217     else 
00218     {
00219       timerRecordStep->stop();    
00220       setPixmap("textures/media-playback-start.png", playforward_record);
00221     }
00222       }
00223 
00224       void RealGUI::slot_stepforward()
00225       {
00226     if (timeSlider->value() != timeSlider->maxValue())
00227     {  
00228       setRecordTime(getRecordTime() + atof(dtEdit->text()));    
00229       slot_loadrecord_timevalue();
00230     }
00231       }
00232 
00233       void RealGUI::slot_forward(  )
00234       {
00235     if (timeSlider->value() != timeSlider->maxValue())
00236     {
00237       setRecordTime(getRecordFinalTime());
00238       slot_sliderValue(timeSlider->maxValue());     
00239     }
00240       }
00241 
00242       void RealGUI::slot_sliderValue(int value)
00243       {
00244     if (timeSlider->value() == value) return;
00245     double init_time   = getRecordInitialTime();
00246     double final_time  = getRecordFinalTime();
00247     double time = init_time + value/((float)timeSlider->maxValue())*(final_time-initial_time);
00248     setRecordTime(time);
00249     timeSlider->setValue(value);
00250     timeSlider->update();
00251     loadSimulation();   
00252       }
00253 
00254       void RealGUI::slot_loadrecord_timevalue()
00255       {       
00256     
00257     double init_time = getRecordInitialTime();
00258     double final_time = getRecordFinalTime();
00259     double current_time = getRecordTime();
00260     
00261     int value = (int)((current_time-init_time)/((float)(final_time-init_time))*timeSlider->maxValue()+0.5);
00262         
00263     if (value >= timeSlider->minValue() && value <= timeSlider->maxValue())    slot_sliderValue(value);
00264     else if (value < timeSlider->minValue())                               slot_sliderValue(timeSlider->minValue());
00265     else if (value > timeSlider->maxValue())
00266     {
00267       playforward_record->setOn(false);
00268       slot_sliderValue(timeSlider->maxValue());
00269       setRecordTime(getRecordFinalTime());
00270       slot_playforward();
00271     }
00272       }
00273 
00274       //-------------------------------------------------
00275       //Given a direction  (forward, or backward), load the samples of the simulation between the initial and final time.
00276       void RealGUI::loadSimulation(bool one_step)
00277       {
00278     if (timeSlider->maxValue() == 0) 
00279     {
00280       playforward_record->setOn(false);
00281       return;
00282     }
00283           
00284     unsigned int sleep_time = clock();
00285     double time=getRecordTime();
00286             
00287     //update the time in the context
00288     viewer->getScene()->execute< sofa::simulation::UpdateSimulationContextVisitor >();
00289     viewer->getScene()->execute< sofa::simulation::VisualUpdateVisitor >();
00290     
00291     //read the state for the current time
00292     sofa::component::misc::ReadStateModifier v(time);
00293     v.execute(viewer->getScene());        
00294         
00295     viewer->getQWidget()->update();
00296         
00297     if (!one_step) sleep((unsigned int)(1000*viewer->getScene()->getDt()), sleep_time); 
00298         
00299     //Exporting sequence of OBJs    
00300     if ( _animationOBJ )
00301       {
00302 #ifdef CAPTURE_PERIOD
00303         static int counter = 0;
00304         if ( ( counter++ % CAPTURE_PERIOD ) ==0 )
00305 #endif
00306           {
00307         exportOBJ ( false );
00308         ++_animationOBJcounter;
00309           }
00310       }
00311     //Exporting states
00312     if ( m_dumpState )
00313       getSimulation()->dumpState ( viewer->getScene(), *m_dumpStateStream );
00314     //Exporting in GNUplot format
00315     if ( m_exportGnuplot )
00316       getSimulation()->exportGnuplot ( viewer->getScene(), viewer->getScene()->getTime() );
00317 
00318     emit newStep();          
00319       }
00320 
00321 
00322       //-------------------------------------------------
00323       double RealGUI::getRecordInitialTime() const
00324       {
00325     std::string init_time = initialTime->text().ascii();
00326     init_time.resize(init_time.size()-2);
00327     return fabs(atof((init_time.substr(6)).c_str()));
00328       }
00329       double RealGUI::getRecordFinalTime() const
00330       {
00331     std::string final_time = finalTime->text().ascii();
00332     final_time.resize(final_time.size()-2);
00333     return fabs(atof((final_time.substr(5)).c_str()));
00334       }
00335       double RealGUI::getRecordTime() const
00336       {
00337     return fabs(atof(loadRecordTime->text().ascii()));
00338       }
00339       void RealGUI::setRecordInitialTime(double time)
00340       {
00341     char buf[100];
00342     sprintf ( buf, "Init: %.3f s", fabs(time) );
00343     initialTime->setText ( buf ); 
00344       }
00345       void RealGUI::setRecordFinalTime(double time)
00346       {
00347     char buf[100];
00348     sprintf ( buf, "End: %.3f s", fabs(time) );
00349     finalTime->setText( buf );  
00350       }
00351       void RealGUI::setRecordTime(double time)
00352       {
00353     char buf[100];
00354     sprintf ( buf, "%.3f", fabs(time) );
00355     loadRecordTime->setText( buf );    
00356     setTimeSimulation(getRecordTime());
00357       }
00358             
00359       void RealGUI::setTimeSimulation(double time)
00360       {
00361     char buf[100];
00362     sprintf ( buf, "Time: %.3f s", time );
00363     timeLabel->setText ( buf ); 
00364     viewer->getScene()->setTime(time);
00365       }
00366     } // namespace qt
00367 
00368   } // namespace gui
00369 
00370 } // namespace sofa

Generated on Sun Nov 23 02:28:36 2008 for Sofa by  doxygen 1.5.7.1