RealGUI.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 <sofa/gui/qt/viewer/qtogre/QtOgreViewer.h>
00031 #endif
00032 
00033 #ifdef SOFA_GUI_QTVIEWER
00034 #include <sofa/gui/qt/viewer/qt/QtViewer.h>
00035 #endif
00036 
00037 #ifdef SOFA_GUI_QGLVIEWER
00038 #include <sofa/gui/qt/viewer/qgl/QtGLViewer.h>
00039 #endif
00040 
00041 #include <sofa/simulation/tree/Simulation.h>
00042 #include <sofa/simulation/common/InitVisitor.h>
00043 #include <sofa/simulation/common/DesactivatedNodeVisitor.h>
00044 
00045 
00046 #ifdef SOFA_HAVE_CHAI3D
00047 #include <sofa/simulation/common/PropagateEventVisitor.h>
00048 #include <sofa/core/objectmodel/GLInitializedEvent.h>
00049 #endif // SOFA_HAVE_CHAI3D
00050 
00051 
00052 #include <sofa/component/visualmodel/VisualModelImpl.h>
00053 
00054 #include <sofa/simulation/tree/xml/XML.h>
00055 #include <sofa/simulation/common/TransformationVisitor.h>
00056 #include <sofa/helper/system/FileRepository.h>
00057 
00058 
00059 
00060 #ifdef SOFA_QT4
00061 #include <QWidget>
00062 #include <QStackedWidget>
00063 #include <QLayout>
00064 #include <Q3ListViewItem>
00065 #include <Q3ListView>
00066 #include <QStatusBar>
00067 #include <QRadioButton>
00068 #include <QCheckBox>
00069 #include <QSplitter>
00070 #include <Q3TextEdit>
00071 #include <QCursor>
00072 #include <QAction>
00073 #include <QMessageBox>
00074 #include <QTabWidget>
00075 #include <QToolTip>
00076 #include <QButtonGroup>
00077 #include <QRadioButton>
00078 #include <QInputDialog>
00079 #else
00080 #include <qwidget.h>
00081 #include <qwidgetstack.h>
00082 #include <qlayout.h>
00083 #include <qlistview.h>
00084 #include <qstatusbar.h>
00085 #include <qheader.h>
00086 #include <qimage.h>
00087 #include <qsplitter.h>
00088 #include <qtextedit.h>
00089 #include <qcursor.h>
00090 #include <qapplication.h>
00091 #include <qaction.h>
00092 #include <qmessagebox.h>
00093 #include <qtabwidget.h>
00094 #include <qtooltip.h>
00095 #include <qbuttongroup.h>
00096 #include <qradiobutton.h>
00097 #include <qinputdialog.h>
00098 #endif
00099 
00100 #include <GenGraphForm.h>
00101 
00102 
00103 
00104 namespace sofa
00105 {
00106 
00107   namespace gui
00108   {
00109 
00110     namespace qt
00111     {
00112 
00113 #ifdef SOFA_QT4
00114       typedef Q3ListView QListView;
00115       typedef Q3DockWindow QDockWindow;
00116       typedef QStackedWidget QWidgetStack;
00117       typedef Q3TextEdit QTextEdit;
00118 #endif
00119 
00120 
00121       using sofa::core::objectmodel::BaseObject;
00122       using sofa::simulation::tree::GNode;
00123       using namespace sofa::helper::system::thread;
00124       using namespace sofa::simulation;
00125       using namespace sofa::simulation::tree;
00126 
00127 
00128 
00132 
00133 #ifdef SOFA_GUI_QGLVIEWER
00134       SOFA_DECL_CLASS ( QGLViewerGUI )
00135       int QGLViewerGUIClass = SofaGUI::RegisterGUI ( "qglviewer", &RealGUI::CreateGUI, &RealGUI::InitGUI, 3 );
00136 #endif
00137 #ifdef SOFA_GUI_QTVIEWER
00138       SOFA_DECL_CLASS ( QTGUI )
00139       int QtGUIClass = SofaGUI::RegisterGUI ( "qt", &RealGUI::CreateGUI, &RealGUI::InitGUI, 2 );
00140 #endif
00141 #ifdef SOFA_GUI_QTOGREVIEWER
00142       SOFA_DECL_CLASS ( OgreGUI )
00143       int QtOGREGUIClass = SofaGUI::RegisterGUI ( "ogre", &RealGUI::CreateGUI, &RealGUI::InitGUI, 1 );
00144 #endif
00145 
00146       int RealGUI::InitGUI ( const char* name, const std::vector<std::string>& /* options */ )
00147       {
00148 #ifdef SOFA_GUI_QGLVIEWER
00149     if ( !name[0] || !strcmp ( name,"qglviewer" ) )
00150       {
00151         return sofa::gui::qt::viewer::qgl::QtGLViewer::EnableViewer();
00152       }
00153     else
00154 #endif
00155 #ifdef SOFA_GUI_QTVIEWER
00156       if ( !name[0] || !strcmp ( name,"qt" ) )
00157         {
00158           return sofa::gui::qt::viewer::qt::QtViewer::EnableViewer();
00159         }
00160       else
00161 #endif
00162 #ifdef SOFA_GUI_QTOGREVIEWER
00163         if ( !name[0] || !strcmp ( name,"ogre" ) )
00164           {
00165         return sofa::gui::qt::viewer::qtogre::QtOgreViewer::EnableViewer();
00166           }
00167         else
00168 #endif
00169           {
00170         std::cerr << "ERROR(QtGUI): unknown or disabled gui name "<<name<<std::endl;
00171         return 1;
00172           }
00173       }
00174 
00175       extern QApplication* application; // = NULL;
00176       extern RealGUI* gui;
00177 
00178 #ifdef SOFA_QT4
00180 class QSOFAApplication : public QApplication
00181 {
00182 public:
00183     QSOFAApplication(int &argc, char ** argv)
00184     : QApplication(argc,argv)
00185     {
00186     }
00187 protected:
00188     bool event(QEvent *event)
00189     {
00190         switch (event->type())
00191     {
00192     case QEvent::FileOpen:
00193       static_cast<RealGUI*>(mainWidget())->fileOpen(static_cast<QFileOpenEvent *>(event)->file().ascii());
00194 
00195         return true;
00196     default:
00197         return QApplication::event(event);
00198     }
00199     }
00200 };
00201 #else
00202 typedef QApplication QSOFAApplication;
00203 #endif
00204 
00205       SofaGUI* RealGUI::CreateGUI ( const char* name, const std::vector<std::string>& options, sofa::simulation::Node* node, const char* filename )
00206       {
00207     {
00208       int argc=1;
00209       char **argv = new char*[2];
00210       argv[0] = strdup ( SofaGUI::GetProgramName() );
00211       argv[1]=NULL;
00212       application = new QSOFAApplication ( argc,argv );
00213     }
00214     // create interface
00215     gui = new RealGUI ( name, options );
00216     GNode *groot = dynamic_cast< GNode* >(node);
00217     if ( groot )
00218         gui->setScene ( groot, filename );
00219 
00220 
00221     else
00222       return NULL;
00223 
00224     //gui->viewer->resetView();
00225 
00226     application->setMainWidget ( gui );
00227 
00228 
00229     // show the gui
00230     gui->show();
00231 
00232 
00233     #ifdef SOFA_HAVE_CHAI3D
00234     // Tell nodes that openGl is initialized
00235     // especialy the GL_MODELVIEW_MATRIX
00236     sofa::core::objectmodel::GLInitializedEvent ev;
00237     sofa::simulation::PropagateEventVisitor act(&ev);
00238     groot->execute(act);
00239     #endif // SOFA_HAVE_CHAI3D
00240 
00241     return gui;
00242       }
00243 
00244       int RealGUI::mainLoop()
00245       {
00246 
00247 #ifdef SOFA_QT4
00248     QString title = windowTitle();
00249 #else
00250     QString title = caption();
00251 #endif
00252 
00253     title.remove(QString("Sofa - "), true);
00254     std::string title_str(title.ascii());
00255 
00256     if ( (title_str.rfind(".simu") != std::string::npos) && sofa::helper::system::DataRepository.findFile (title_str) )
00257     {
00258       title_str = sofa::helper::system::DataRepository.getFile ( title_str );
00259 
00260       fileOpenSimu(title_str.c_str() );
00261     }
00262 
00263 
00264 
00265     return application->exec();
00266       }
00267 
00268       void RealGUI::redraw()
00269       {
00270     viewer->getQWidget()->update();
00271       }
00272 
00273       int RealGUI::closeGUI()
00274       {
00275     delete this;
00276     return 0;
00277       }
00278 
00279       Node* RealGUI::currentSimulation()
00280       {
00281     return viewer->getScene();
00282       }
00283 
00284 
00285 
00286 
00287       RealGUI::RealGUI ( const char* viewername, const std::vector<std::string>& /*options*/ )
00288     : viewerName ( viewername ), viewer ( NULL ), currentTab ( NULL ), tabInstrument (NULL),  graphListener ( NULL ), dialog ( NULL )
00289       {
00290     connect(this, SIGNAL(quit()), this, SLOT(fileExit()));
00291 
00292 #ifdef SOFA_QT4 
00293     fileMenu->removeAction(Action);
00294 #endif
00295 
00296     displayFlag = new DisplayFlagWidget(tabView);           
00297     connect( displayFlag, SIGNAL( change(int,bool)), this, SLOT(showhideElements(int,bool) ));
00298     gridLayout1->addWidget(displayFlag,0,0);
00299     
00300 
00301     left_stack = new QWidgetStack ( splitter2 );
00302     connect ( startButton, SIGNAL ( toggled ( bool ) ), this , SLOT ( playpauseGUI ( bool ) ) );
00303 
00304 
00305     //Status Bar Configuration
00306     fpsLabel = new QLabel ( "9999.9 FPS", statusBar() );
00307     fpsLabel->setMinimumSize ( fpsLabel->sizeHint() );
00308     fpsLabel->clear();
00309 
00310     timeLabel = new QLabel ( "Time: 999.9999 s", statusBar() );
00311     timeLabel->setMinimumSize ( timeLabel->sizeHint() );
00312     timeLabel->clear();
00313 
00314     initialTime = new QLabel( "Init:", statusBar() );
00315     initialTime->setMinimumSize ( initialTime->sizeHint() );
00316 
00317     timeSlider = new QSlider( Qt::Horizontal, statusBar(), "Time Slider");
00318     timeSlider->setTickmarks(QSlider::Both);
00319     timeSlider->setMinValue(0);
00320     timeSlider->setMaxValue(0);
00321 
00322     finalTime = new QLabel( "End:", statusBar() );
00323     finalTime->setMinimumSize ( finalTime->sizeHint() );
00324 
00325     std::string pixmap_filename;
00326 
00327     record                 = new QPushButton( statusBar(), "Record");   record->setToggleButton(true);
00328     backward_record        = new QPushButton( statusBar(), "Backward");
00329     stepbackward_record    = new QPushButton( statusBar(), "Step Backward");
00330     playforward_record     = new QPushButton( statusBar(), "Play Forward"); playforward_record->setToggleButton(true);
00331     stepforward_record     = new QPushButton( statusBar(), "Step Forward");
00332     forward_record         = new QPushButton( statusBar(), "Forward");
00333 
00334     QToolTip::add(record               , tr( "Record" ) );
00335     QToolTip::add(backward_record      , tr( "Load Initial Time" ) );
00336     QToolTip::add(stepbackward_record  , tr( "Make one step backward" ) );
00337     QToolTip::add(playforward_record   , tr( "Continuous play forward" ) );
00338     QToolTip::add(stepforward_record   , tr( "Make one step forward" ) );
00339     QToolTip::add(forward_record       , tr( "Load Final Time" ) );
00340 
00341 
00342     setPixmap("textures/media-record.png", record);
00343     setPixmap("textures/media-seek-backward.png", backward_record);
00344     setPixmap("textures/media-skip-backward.png", stepbackward_record);
00345     setPixmap("textures/media-playback-start.png", playforward_record);
00346     setPixmap("textures/media-skip-forward.png", stepforward_record);
00347     setPixmap("textures/media-seek-forward.png", forward_record);
00348 
00349 
00350     QLabel *timeRecord = new QLabel("T=",statusBar());
00351     loadRecordTime = new QLineEdit(statusBar());
00352     loadRecordTime->setMaximumSize(QSize(50, 100));
00353 
00354 
00355     statusBar()->addWidget ( fpsLabel );
00356     statusBar()->addWidget ( timeLabel );
00357 
00358     statusBar()->addWidget( record);
00359     statusBar()->addWidget( backward_record);
00360     statusBar()->addWidget( stepbackward_record);
00361     statusBar()->addWidget( playforward_record);
00362     statusBar()->addWidget( stepforward_record);
00363     statusBar()->addWidget( forward_record);
00364     statusBar()->addWidget( timeRecord);
00365 
00366     statusBar()->addWidget( loadRecordTime);
00367 
00368     statusBar()->addWidget ( initialTime );
00369     statusBar()->addWidget( timeSlider);
00370     statusBar()->addWidget ( finalTime );
00371 
00372     timerStep       = new QTimer ( this );
00373     timerRecordStep = new QTimer ( this );
00374 
00375 
00376     connect ( timerStep, SIGNAL ( timeout() ), this, SLOT ( step() ) );
00377     connect ( timerRecordStep, SIGNAL ( timeout() ), this, SLOT ( slot_stepforward() ) );
00378     connect ( ResetSceneButton, SIGNAL ( clicked() ), this, SLOT ( resetScene() ) );
00379     connect ( dtEdit, SIGNAL ( textChanged ( const QString& ) ), this, SLOT ( setDt ( const QString& ) ) );
00380     connect ( stepButton, SIGNAL ( clicked() ), this, SLOT ( step() ) );
00381     connect ( ExportGraphButton, SIGNAL ( clicked() ), this, SLOT ( exportGraph() ) );
00382     connect ( dumpStateCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT ( dumpState ( bool ) ) );
00383     connect ( exportGnuplotFilesCheckbox, SIGNAL ( toggled ( bool ) ), this, SLOT ( setExportGnuplot ( bool ) ) );
00384     connect ( displayComputationTimeCheckBox, SIGNAL ( toggled ( bool ) ), this, SLOT ( displayComputationTime ( bool ) ) );
00385 
00386     connect ( record, SIGNAL (toggled (bool) ),              this, SLOT( slot_recordSimulation( bool) ) );
00387     connect ( backward_record, SIGNAL (clicked () ),         this, SLOT( slot_backward( ) ) );
00388     connect ( stepbackward_record, SIGNAL (clicked () ),     this, SLOT( slot_stepbackward( ) ) );
00389     connect ( playforward_record,  SIGNAL (clicked () ),     this, SLOT( slot_playforward( ) ) );
00390     connect ( stepforward_record,  SIGNAL (clicked () ),     this, SLOT( slot_stepforward( ) ) );
00391     connect ( forward_record, SIGNAL (clicked () ),          this, SLOT( slot_forward( ) ) );
00392     connect ( loadRecordTime, SIGNAL(returnPressed ()),       this, SLOT( slot_loadrecord_timevalue()));
00393     connect ( timeSlider, SIGNAL (sliderMoved (int) ),   this, SLOT( slot_sliderValue( int) ) );
00394 
00395 
00396     connect( recentlyOpened, SIGNAL(activated(int)), this, SLOT(fileRecentlyOpened(int)));
00397     //Recently Opened Files
00398     std::string scenes ( "config/Sofa.ini" );
00399     if ( !sofa::helper::system::DataRepository.findFile ( scenes ) )
00400     {
00401         std::string fileToBeCreated = sofa::helper::system::DataRepository.getFirstPath() + "/" + scenes;
00402 
00403         std::ofstream ofile(fileToBeCreated.c_str());
00404         ofile << "";
00405         ofile.close();
00406     }
00407 
00408     scenes = sofa::helper::system::DataRepository.getFile ( scenes );
00409 
00410     updateRecentlyOpened("");
00411 
00412 
00413     //Dialog Add Object
00414     connect ( tabs, SIGNAL ( currentChanged ( QWidget* ) ), this, SLOT ( currentTabChanged ( QWidget* ) ) );
00415 
00416     addViewer();
00417     currentTabChanged ( tabs->currentPage() );
00418 
00419 
00420 #ifdef SOFA_PML
00421     pmlreader = NULL;
00422     lmlreader = NULL;
00423 #endif
00424 
00425     //Center the application
00426     const QRect screen = QApplication::desktop()->availableGeometry(QApplication::desktop()->primaryScreen());
00427     this->move(  ( screen.width()- this->width()  ) / 2,  ( screen.height() - this->height()) / 2  );
00428 
00429       }
00430 
00431       void RealGUI::fileRecentlyOpened(int id)
00432       {
00433     fileOpen(recentlyOpened->text(id).ascii());
00434       }
00435 
00436       void RealGUI::updateRecentlyOpened(std::string fileLoaded)
00437       {
00438 
00439 #ifdef WIN32
00440     for (unsigned int i=0;i<fileLoaded.size();++i)
00441       {
00442         if (fileLoaded[i] == '\\') fileLoaded[i] = '/';
00443       }          
00444 #endif
00445     std::string scenes ( "config/Sofa.ini" );
00446 
00447     scenes = sofa::helper::system::DataRepository.getFile ( scenes );
00448 
00449     std::vector< std::string > list_files;
00450     std::ifstream end(scenes.c_str());
00451     std::string s;
00452     while( std::getline(end,s) )
00453       {
00454         if (s != fileLoaded)
00455           list_files.push_back(sofa::helper::system::DataRepository.getFile(s));
00456       }
00457     end.close();
00458 
00459 
00460     recentlyOpened->clear();
00461     std::ofstream out;
00462     out.open(scenes.c_str(),std::ios::out);
00463     if (sofa::helper::system::DataRepository.findFile(fileLoaded))
00464       {
00465         fileLoaded = sofa::helper::system::DataRepository.getFile(fileLoaded);
00466         out << fileLoaded << "\n";
00467 
00468         recentlyOpened->insertItem(QString(fileLoaded.c_str()));
00469       }
00470     for (unsigned int i=0;i<list_files.size() && i<5 ;++i)
00471       {
00472         if (fileLoaded != list_files[i])
00473           {
00474         recentlyOpened->insertItem(QString(list_files[i].c_str()));
00475         out << list_files[i] << "\n";
00476           }
00477       }
00478 
00479     out.close();
00480 
00481 
00482       }
00483 
00484       void RealGUI::setPixmap(std::string pixmap_filename, QPushButton* b)
00485       {
00486     if ( sofa::helper::system::DataRepository.findFile ( pixmap_filename ) )
00487       pixmap_filename = sofa::helper::system::DataRepository.getFile ( pixmap_filename );
00488     b->setPixmap(QPixmap(QImage(pixmap_filename.c_str())));
00489       }
00490 
00491       RealGUI::~RealGUI()
00492       {
00493 #ifdef SOFA_PML
00494     if ( pmlreader )
00495       {
00496         delete pmlreader;
00497         pmlreader = NULL;
00498       }
00499     if ( lmlreader )
00500       {
00501         delete lmlreader;
00502         lmlreader = NULL;
00503       }
00504 #endif
00505       }
00506 
00507       void RealGUI::init()
00508       {
00509 
00510     frameCounter = 0;
00511     node_clicked = NULL;
00512     item_clicked = NULL;
00513     _animationOBJ = false;
00514     _animationOBJcounter = 0;
00515     m_dumpState = false;
00516     m_dumpStateStream = 0;
00517     m_displayComputationTime = false;
00518     m_exportGnuplot = false;
00519     record_directory = sofa::helper::system::SetDirectory::GetRelativeFromDir("../../examples/Simulation/",sofa::helper::system::SetDirectory::GetProcessFullPath("").c_str());
00520     gnuplot_directory = "";
00521     writeSceneName = "";
00522 
00523     current_Id_modifyDialog = 0;
00524     map_modifyDialogOpened.clear();
00525 
00526 
00527     //*********************************************************************************************************************************
00528     //List of objects
00529     //Read the object.txt that contains the information about the objects which can be added to the scenes whithin a given BoundingBox and scale range
00530     std::string object ( "config/object.txt" );
00531     if ( !sofa::helper::system::DataRepository.findFile ( object ) )
00532       return;
00533 
00534     object = sofa::helper::system::DataRepository.getFile ( object );
00535     list_object.clear();
00536     std::ifstream end(object.c_str());
00537     std::string s;
00538     while( end >> s ) {
00539       list_object.push_back(s);
00540     }
00541     end.close();
00542       }
00543 
00544       void RealGUI::addViewer()
00545       {
00546     init();
00547     const char* name = viewerName;
00548 
00549     // set menu state
00550 
00551 #ifdef SOFA_GUI_QTVIEWER
00552     viewerOpenGLAction->setEnabled ( true );
00553 #else
00554     viewerOpenGLAction->setEnabled ( false );
00555     viewerOpenGLAction->setToolTip ( "enable SOFA_GUI_QTVIEWER in sofa-local.cfg to activate" );
00556 #endif
00557 #ifdef SOFA_GUI_QGLVIEWER
00558     viewerQGLViewerAction->setEnabled ( true );
00559 #else
00560     viewerQGLViewerAction->setEnabled ( false );
00561     viewerQGLViewerAction->setToolTip ( "enable SOFA_GUI_QGLVIEWER in sofa-local.cfg to activate" );
00562 #endif
00563 #ifdef SOFA_GUI_QTOGREVIEWER
00564     viewerOGREAction->setEnabled ( true );
00565 #else
00566     viewerOGREAction->setEnabled ( false );
00567     viewerOGREAction->setToolTip ( "enable SOFA_GUI_QTOGREVIEWER in sofa-local.cfg to activate" );
00568 #endif
00569 
00570 #ifdef SOFA_GUI_QGLVIEWER
00571     if ( !name[0] || !strcmp ( name,"qglviewer" ) )
00572       {
00573         viewer = new sofa::gui::qt::viewer::qgl::QtGLViewer ( left_stack, "viewer" );
00574         viewerQGLViewerAction->setOn ( true );
00575       }
00576     else
00577 #endif
00578 #ifdef SOFA_GUI_QTVIEWER
00579       if ( !name[0] || !strcmp ( name,"qt" ) )
00580         {
00581           viewer = new sofa::gui::qt::viewer::qt::QtViewer ( left_stack, "viewer" );
00582           viewerOpenGLAction->setOn ( true );
00583         }
00584       else
00585 #endif
00586 #ifdef SOFA_GUI_QTOGREVIEWER
00587         if ( !name[0] || !strcmp ( name,"ogre" ) )
00588           {
00589         viewer = new sofa::gui::qt::viewer::qtogre::QtOgreViewer ( left_stack , "viewer" );
00590         viewerOGREAction->setOn ( true );
00591           }
00592         else
00593 #endif
00594           {
00595         std::cerr << "ERROR(QtGUI): unknown or disabled viewer name "<<name<<std::endl;
00596         application->exit();
00597           }
00598 #ifdef SOFA_QT4
00599     left_stack->addWidget ( viewer->getQWidget() );
00600     left_stack->setCurrentWidget ( viewer->getQWidget() );
00601 #else
00602     int id_viewer = left_stack->addWidget ( viewer->getQWidget() );
00603     left_stack->raiseWidget ( id_viewer );
00604 #endif
00605     viewer->getQWidget()->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 7, ( QSizePolicy::SizeType ) 7, 100, 1,
00606                                 viewer->getQWidget()->sizePolicy().hasHeightForWidth() ) );
00607     viewer->getQWidget()->setMinimumSize ( QSize ( 0, 0 ) );
00608 #ifndef SOFA_QT4
00609     viewer->getQWidget()->setCursor ( QCursor ( 2 ) );
00610 #endif
00611     viewer->getQWidget()->setMouseTracking ( TRUE );
00612 
00613 #ifdef SOFA_QT4
00614     viewer->getQWidget()->setFocusPolicy ( Qt::StrongFocus );
00615 #else
00616     viewer->getQWidget()->setFocusPolicy ( QWidget::StrongFocus );
00617 #endif
00618 
00619     viewer->setup();
00620 
00621     connect ( ResetViewButton, SIGNAL ( clicked() ), viewer->getQWidget(), SLOT ( resetView() ) );
00622     connect ( SaveViewButton, SIGNAL ( clicked() ), viewer->getQWidget(), SLOT ( saveView() ) );
00623     connect ( screenshotButton, SIGNAL ( clicked() ), this, SLOT ( screenshot() ) );
00624     connect ( sizeW, SIGNAL ( valueChanged ( int ) ), viewer->getQWidget(), SLOT ( setSizeW ( int ) ) );
00625     connect ( sizeH, SIGNAL ( valueChanged ( int ) ), viewer->getQWidget(), SLOT ( setSizeH ( int ) ) );
00626     connect ( viewer->getQWidget(), SIGNAL ( resizeW ( int ) ), sizeW, SLOT ( setValue ( int ) ) );
00627     connect ( viewer->getQWidget(), SIGNAL ( resizeH ( int ) ), sizeH, SLOT ( setValue ( int ) ) );
00628 
00629     QSplitter *splitter_ptr = dynamic_cast<QSplitter *> ( splitter2 );
00630     splitter_ptr->moveToLast ( left_stack );
00631     splitter_ptr->setOpaqueResize ( false );
00632 #ifdef SOFA_QT4
00633         splitter_ptr->setStretchFactor( 0, 0);
00634         QList<int> list;
00635 #else
00636     QValueList<int> list;
00637 #endif
00638     list.push_back ( 259 );
00639     list.push_back ( 525 );
00640     splitter_ptr->setSizes ( list );
00641 
00642     viewer->getQWidget()->setFocus();
00643     viewer->getQWidget()->show();
00644     viewer->getQWidget()->update();
00645     setGUI();
00646 
00647 
00648       }
00649 
00650       void RealGUI::viewerOpenGL()
00651       {
00652     setViewer ( "qt" );
00653     viewerOpenGLAction->setOn(true);
00654     viewerQGLViewerAction->setOn(false);
00655     viewerOGREAction->setOn(false);
00656       }
00657 
00658       void RealGUI::viewerQGLViewer()
00659       {
00660     setViewer ( "qglviewer" );
00661     viewerOpenGLAction->setOn(false);
00662     viewerQGLViewerAction->setOn(true);
00663     viewerOGREAction->setOn(false);
00664       }
00665 
00666       void RealGUI::viewerOGRE()
00667       {
00668     setViewer ( "ogre" );
00669     viewerOpenGLAction->setOn(false);
00670     viewerQGLViewerAction->setOn(false);
00671     viewerOGREAction->setOn(true);
00672       }
00673 
00674       bool RealGUI::setViewer ( const char* name )
00675       {
00676     if ( !strcmp ( name,viewerName ) )
00677       return true; // nothing to do
00678     if ( !strcmp ( name,"qt" ) )
00679       {
00680 #ifndef SOFA_GUI_QTVIEWER
00681         std::cerr << "OpenGL viewer not activated. Enable SOFA_GUI_QGLVIEWER in sofa-local.cfg to activate.\n";
00682         return false;
00683 #endif
00684       }
00685     else if ( !strcmp ( name,"qglviewer" ) )
00686       {
00687 #ifndef SOFA_GUI_QGLVIEWER
00688         std::cerr << "QGLViewer viewer not activated. Enable SOFA_GUI_QGLVIEWER in sofa-local.cfg to activate.\n";
00689         return false;
00690 #endif
00691       }
00692     else if ( !strcmp ( name,"ogre" ) )
00693       {
00694 #ifndef SOFA_GUI_QTOGREVIEWER
00695         std::cerr << "OGRE viewer not activated. Enable SOFA_GUI_QTOGREVIEWER in sofa-local.cfg to activate.\n";
00696         return false;
00697 #endif
00698       }
00699     else
00700       {
00701         std::cerr << "Unknown viewer.\n";
00702         return false;
00703       }
00704     if ( QMessageBox::warning ( this, "Changing Viewer", "Changing viewer requires to reload the current scene.\nAre you sure you want to do that ?", QMessageBox::Yes | QMessageBox::Default, QMessageBox::No ) != QMessageBox::Yes )
00705       return false;
00706 
00707 
00708     std::string filename = viewer->getSceneFileName();
00709 
00710     if ( viewer->getScene() !=NULL )
00711     {
00712         getSimulation()->unload ( viewer->getScene() );
00713       if ( graphListener!=NULL )
00714       {
00715         delete graphListener;
00716         graphListener = NULL;
00717       }
00718       graphView->clear();
00719     }
00720 
00721 //  fileOpen(filename);
00722 //  GNode* groot = new GNode; // empty scene to do the transition
00723 //  setScene ( groot,filename.c_str() ); // keep the current display flags
00724     left_stack->removeWidget ( viewer->getQWidget() );
00725     delete viewer;
00726     viewer = NULL;
00727     // Disable Viewer-specific classes
00728 #ifdef SOFA_GUI_QTVIEWER
00729     if ( !strcmp ( viewerName,"qt" ) )
00730       {
00731         sofa::gui::qt::viewer::qt::QtViewer::DisableViewer();
00732       }
00733     else
00734 #endif
00735 #ifdef SOFA_GUI_QGLVIEWER
00736       if ( !strcmp ( viewerName,"qglviewer" ) )
00737         {
00738           sofa::gui::qt::viewer::qgl::QtGLViewer::DisableViewer();
00739         }
00740       else
00741 #endif
00742 #ifdef SOFA_GUI_QTOGREVIEWER
00743         if ( !strcmp ( viewerName,"ogre" ) )
00744           {
00745         sofa::gui::qt::viewer::qtogre::QtOgreViewer::DisableViewer();
00746           }
00747         else
00748 #endif
00749           {}
00750     // Enable Viewer-specific classes
00751 #ifdef SOFA_GUI_QTVIEWER
00752     if ( !strcmp ( name,"qt" ) )
00753       {
00754         sofa::gui::qt::viewer::qt::QtViewer::EnableViewer();
00755       }
00756     else
00757 #endif
00758 #ifdef SOFA_GUI_QGLVIEWER
00759       if ( !strcmp ( name,"qglviewer" ) )
00760         {
00761           sofa::gui::qt::viewer::qgl::QtGLViewer::EnableViewer();
00762         }
00763       else
00764 #endif
00765 #ifdef SOFA_GUI_QTOGREVIEWER
00766         if ( !strcmp ( name,"ogre" ) )
00767           {
00768         sofa::gui::qt::viewer::qtogre::QtOgreViewer::EnableViewer();
00769           }
00770 #endif
00771 
00772 
00773     viewerName = name;
00774 
00775     addViewer();
00776 
00777     if (filename.rfind(".simu") != std::string::npos)
00778       fileOpenSimu(filename.c_str() );
00779     //else if (filename.rfind(".pscn") != std::string::npos)
00780     //  fileOpenScript(filename.c_str(), PHP );
00781     //else
00782         fileOpen ( filename.c_str() ); // keep the current display flags
00783     return true;
00784       }
00785 
00786       void RealGUI::fileOpen ( std::string filename )
00787       {
00788 
00789     if ( sofa::helper::system::DataRepository.findFile (filename) )
00790       filename = sofa::helper::system::DataRepository.getFile ( filename );
00791     else
00792       return;
00793 
00794 
00795 
00796     frameCounter = 0;
00797     sofa::simulation::tree::xml::numDefault = 0;
00798     list_object_added.clear();
00799     list_object_removed.clear();
00800     list_object_initial.clear();
00801     writeSceneName="";
00802 
00803     update();
00804 
00805     //Hide the dialog to add a new object in the graph
00806     if ( dialog != NULL ) dialog->hide();
00807     //Hide all the dialogs to modify the graph
00808     emit ( newScene() );
00809 
00810     if ( viewer->getScene() !=NULL )
00811     {
00812         getSimulation()->unload ( viewer->getScene() );
00813       if ( graphListener!=NULL )
00814       {
00815         delete graphListener;
00816         graphListener = NULL;
00817       }
00818       graphView->clear();
00819     }
00820 
00821     //Clear the list of modified dialog opened
00822     current_Id_modifyDialog=0;
00823     map_modifyDialogOpened.clear();
00824 
00825     simulation::Node* groot = getSimulation()->load ( filename.c_str() );
00826 
00827     if ( groot == NULL )
00828       {
00829         qFatal ( "Failed to load %s",filename.c_str() );
00830         return;
00831       }
00832 
00833     setScene ( groot, filename.c_str() );
00834     //need to create again the output streams !!
00835 
00836     getSimulation()->gnuplotDirectory.setValue(gnuplot_directory);
00837     setExportGnuplot(exportGnuplotFilesCheckbox->isChecked());
00838 
00839     displayComputationTime(m_displayComputationTime);
00840       }
00841 
00842 #ifdef SOFA_PML
00843       void RealGUI::pmlOpen ( const char* filename, bool /*resetView*/ )
00844       {
00845     std::string scene = "PML/default.scn";
00846     if ( !sofa::helper::system::DataRepository.findFile ( scene ) )
00847       {
00848         std::cerr << "File " << scene << " not found " << std::endl;
00849         return;
00850       }
00851     if ( viewer->getScene() !=NULL )
00852     {
00853       getSimulation()->unload ( viewer->getScene() );
00854       if ( graphListener!=NULL )
00855       {
00856         delete graphListener;
00857         graphListener = NULL;
00858       }
00859       graphView->clear();
00860     }
00861     GNode *simuNode = dynamic_cast< GNode *> (getSimulation()->load ( scene.c_str() ));
00862     if ( simuNode )
00863       {
00864         if ( !pmlreader ) pmlreader = new PMLReader;
00865         pmlreader->BuildStructure ( filename, simuNode );
00866         setScene ( simuNode, filename );
00867       }
00868       }
00869 
00870       void RealGUI::lmlOpen ( const char* filename )
00871       {
00872     if ( pmlreader )
00873       {
00874         Node* groot;
00875         if ( lmlreader != NULL ) delete lmlreader;
00876         lmlreader = new LMLReader; std::cout <<"New lml reader\n";
00877         lmlreader->BuildStructure ( filename, pmlreader );
00878 
00879         groot = viewer->getScene();
00880         getSimulation()->init ( groot );
00881 
00882       }
00883     else
00884       std::cerr<<"You must load the pml file before the lml file"<<endl;
00885       }
00886 #endif
00887 
00888       void RealGUI::initDesactivatedNode()
00889       {
00890 
00891     std::map<core::objectmodel::Base*, QListViewItem* >::iterator graph_iterator;
00892 
00893     for (graph_iterator = graphListener->items.begin(); graph_iterator != graphListener->items.end(); graph_iterator++)
00894     {
00895       node_clicked = dynamic_cast< GNode* >(graph_iterator->first);
00896       if (node_clicked!=NULL )
00897       {
00898        if (!node_clicked->isActive() )
00899        {
00900          item_clicked =  graphListener->items[node_clicked];
00901          graphDesactivateNode();
00902        }
00903       }
00904     }
00905       }
00906 
00907 
00908       void RealGUI::setScene ( Node* groot, const char* filename )
00909       {
00910     if (filename)
00911     {
00912       updateRecentlyOpened(filename);
00913       setTitle ( filename );
00914     }
00915 
00916     if (tabInstrument!= NULL)
00917     {
00918       tabs->removePage(tabInstrument);
00919       delete tabInstrument;
00920       tabInstrument = NULL;
00921     }
00922 
00923 
00924 
00925     viewer->setScene ( dynamic_cast< GNode *>(groot), filename );
00926     viewer->resetView();
00927     initial_time = groot->getTime();
00928 
00929     record_simulation = false;
00930     clearRecord();
00931     clearGraph();
00932 
00933     initDesactivatedNode();
00934 
00935     eventNewTime();
00936 
00937     // set state of display flags
00938     displayFlag->setFlag(DisplayFlagWidget::VISUAL,groot->getContext()->getShowVisualModels());
00939     displayFlag->setFlag(DisplayFlagWidget::BEHAVIOR,groot->getContext()->getShowBehaviorModels());
00940     displayFlag->setFlag(DisplayFlagWidget::COLLISION,groot->getContext()->getShowCollisionModels());
00941     displayFlag->setFlag(DisplayFlagWidget::BOUNDING,groot->getContext()->getShowBoundingCollisionModels());
00942     displayFlag->setFlag(DisplayFlagWidget::MAPPING,groot->getContext()->getShowMappings());
00943     displayFlag->setFlag(DisplayFlagWidget::MECHANICALMAPPING,groot->getContext()->getShowMechanicalMappings());
00944     displayFlag->setFlag(DisplayFlagWidget::FORCEFIELD,groot->getContext()->getShowForceFields());
00945     displayFlag->setFlag(DisplayFlagWidget::INTERACTION,groot->getContext()->getShowInteractionForceFields());
00946     displayFlag->setFlag(DisplayFlagWidget::WIREFRAME,groot->getContext()->getShowWireFrame());
00947     displayFlag->setFlag(DisplayFlagWidget::NORMALS,groot->getContext()->getShowNormals());
00948 
00949     //getSimulation()->updateVisualContext ( groot );
00950     startButton->setOn ( groot->getContext()->getAnimate() );
00951     dtEdit->setText ( QString::number ( groot->getDt() ) );
00952     record->setOn(false);
00953 
00954 #ifdef SOFA_HAVE_CHAI3D
00955     // Tell nodes that openGl is initialized
00956     // especialy the GL_MODELVIEW_MATRIX
00957     sofa::core::objectmodel::GLInitializedEvent ev;
00958     sofa::simulation::PropagateEventVisitor act(&ev);
00959     groot->execute(act);
00960 #endif // SOFA_HAVE_CHAI3D
00961 
00962 
00963 }
00964 
00965       void RealGUI::changeInstrument(int id)
00966       {
00967           std::cout << "Activation instrument "<<id<<std::endl;
00968     Simulation *s = getSimulation();
00969     if (s->instrumentInUse.getValue() >= 0 && s->instrumentInUse.getValue() < (int)s->instruments.size())
00970      s->instruments[s->instrumentInUse.getValue()]->setActive(false);
00971 
00972     getSimulation()->instrumentInUse.setValue(id-1);
00973     if (s->instrumentInUse.getValue() >= 0 && s->instrumentInUse.getValue() < (int)s->instruments.size())
00974      s->instruments[s->instrumentInUse.getValue()]->setActive(true);
00975     viewer->getQWidget()->update();
00976       }
00977 
00978 
00979       void RealGUI::screenshot()
00980       {
00981 
00982     QString filename;
00983 
00984 #ifdef SOFA_HAVE_PNG
00985     const char* imageString = "Images (*.png)";
00986 #else
00987     const char* imageString = "Images (*.bmp)";
00988 #endif
00989 
00990     filename = getSaveFileName ( this,
00991                          viewer->screenshotName().c_str(),
00992                          imageString,
00993                          "save file dialog"
00994                          "Choose a filename to save under" );
00995     viewer->getQWidget()->repaint();
00996     if ( filename != "" )
00997       {
00998         std::ostringstream ofilename;
00999         const char* begin = filename;
01000         const char* end = strrchr ( begin,'_' );
01001         if ( !end ) end = begin + filename.length();
01002         ofilename << std::string ( begin, end );
01003         ofilename << "_";
01004         viewer->setPrefix ( ofilename.str() );
01005 #ifdef SOFA_QT4
01006         viewer->screenshot ( filename.toStdString() );
01007 #else
01008         viewer->screenshot ( filename );
01009 #endif
01010 
01011       }
01012       }
01013 
01014       void RealGUI::fileOpenSimu ( std::string s )
01015       {
01016     std::ifstream in(s.c_str());
01017 
01018     if (!in.fail())
01019       {
01020         std::string filename;
01021         std::string initT, endT, dT, writeName;
01022         in
01023           >> filename
01024           >> initT >> initT
01025           >> endT  >> endT >> endT
01026           >> dT >> dT
01027         >> writeName >> writeName;
01028         in.close();
01029 
01030 
01031 
01032         if ( sofa::helper::system::DataRepository.findFile (filename) )
01033           {
01034         filename = sofa::helper::system::DataRepository.getFile ( filename );
01035         simulation_name = s;
01036         std::string::size_type pointSimu = simulation_name.rfind(".simu");
01037         simulation_name.resize(pointSimu);
01038         fileOpen(filename.c_str());
01039 
01040         writeSceneName = writeName;
01041         addReadState(true);
01042 
01043 
01044         char buf[100];
01045 
01046         sprintf ( buf, "Init: %s s",initT.c_str()  );
01047         initialTime->setText ( buf );
01048 
01049         sprintf ( buf, "End: %s s",endT.c_str()  );
01050         finalTime->setText ( buf );
01051 
01052         loadRecordTime->setText( QString(initT.c_str()) );
01053 
01054         dtEdit->setText(QString(dT.c_str()));
01055         timeSlider->setMaxValue( (int)((atof(endT.c_str())-atof(initT.c_str()))/(atof(dT.c_str()))+0.5));
01056 
01057         record_directory = sofa::helper::system::SetDirectory::GetParentDir(filename.c_str()) + "/";
01058           }
01059       }
01060       }
01061       void RealGUI::fileNew()
01062       {
01063     std::string newScene("config/newScene.scn");
01064     if (sofa::helper::system::DataRepository.findFile (newScene))
01065       fileOpen(sofa::helper::system::DataRepository.getFile ( newScene ).c_str());
01066       }
01067       void RealGUI::fileOpen()
01068       {
01069     std::string filename = viewer->getSceneFileName();
01070 
01071     QString s = getOpenFileName ( this, filename.empty() ?NULL:filename.c_str(),
01072 #ifdef SOFA_PML
01073         "Scenes (*.scn *.xml *.simu *.pml *.lml)",
01074 #else
01075         "Scenes (*.scn *.xml *.simu *.pscn)",
01076 #endif
01077         "open file dialog",  "Choose a file to open" );
01078 
01079     if ( s.length() >0 )
01080       {
01081 #ifdef SOFA_PML
01082         if ( s.endsWith ( ".pml" ) )
01083           pmlOpen ( s );
01084         else if ( s.endsWith ( ".lml" ) )
01085           lmlOpen ( s );
01086         else
01087 #endif
01088             if (s.endsWith( ".simu") )
01089           fileOpenSimu(s.ascii());
01090         else
01091           {
01092         fileOpen (s.ascii());
01093           }
01094       }
01095       }
01096 
01097       void RealGUI::fileReload()
01098       {
01099 
01100     std::string filename = viewer->getSceneFileName();
01101     QString s = filename.c_str();
01102 
01103     if ( filename.empty() ) { std::cerr << "Reload failed: no file loaded.\n"; return;}
01104 
01105 #ifdef SOFA_PML
01106     if ( s.length() >0 )
01107       {
01108         if ( s.endsWith ( ".pml" ) )
01109           pmlOpen ( s );
01110         else if ( s.endsWith ( ".lml" ) )
01111           lmlOpen ( s );
01112         else if (s.endsWith( ".simu") )
01113           fileOpenSimu(filename);
01114         else
01115           fileOpen ( filename );
01116       }
01117 #else
01118     if (s.endsWith( ".simu") )
01119       fileOpenSimu(s.ascii());
01120     else
01121       fileOpen ( s.ascii() );
01122 #endif
01123 
01124       }
01125 
01126       void RealGUI::fileSave()
01127       {
01128     GNode *node = viewer->getScene();
01129     std::string filename = viewer->getSceneFileName();
01130     fileSaveAs ( node,filename.c_str() );
01131       }
01132 
01133 
01134       void RealGUI::fileSaveAs(Node *node)
01135       {
01136     if (node == NULL) node = viewer->getScene();
01137     QString s;
01138     std::string filename = viewer->getSceneFileName();
01139 #ifdef SOFA_PML
01140     s = getSaveFileName ( this, filename.empty() ?NULL:filename.c_str(), "Scenes (*.scn *.xml *.pml)", "save file dialog",  "Choose where the scene will be saved" );
01141     if ( s.length() >0 )
01142       {
01143         if ( pmlreader && s.endsWith ( ".pml" ) )
01144           pmlreader->saveAsPML ( s );
01145         else
01146           fileSaveAs ( node,s );
01147       }
01148 #else
01149     s = getSaveFileName ( this, filename.empty() ?NULL:filename.c_str(), "Scenes (*.scn *.xml)", "save file dialog", "Choose where the scene will be saved" );
01150     if ( s.length() >0 )
01151       fileSaveAs ( node,s );
01152 #endif
01153 
01154       }
01155 
01156       void RealGUI::fileSaveAs ( Node *node, const char* filename )
01157       {
01158     getSimulation()->printXML ( node, filename );
01159       }
01160 
01161       void RealGUI::fileExit()
01162       { 
01163     startButton->setOn ( false);
01164     close();
01165       }
01166 
01167       void RealGUI::saveXML()
01168       {
01169     getSimulation()->printXML ( viewer->getScene(), "scene.scn" );
01170       }
01171 
01172       void RealGUI::editRecordDirectory()
01173       {
01174     std::string filename = viewer->getSceneFileName();
01175     QString s = getExistingDirectory ( this, filename.empty() ?NULL:filename.c_str(), "open directory dialog",  "Choose a directory" );
01176     if (s.length() > 0)
01177       {
01178         record_directory = s.ascii();
01179         if (record_directory.at(record_directory.size()-1) != '/') record_directory+="/";
01180       }
01181 
01182       }
01183 
01184       void RealGUI::editGnuplotDirectory()
01185       {
01186     std::string filename = viewer->getSceneFileName();
01187     QString s = getExistingDirectory ( this, filename.empty() ?NULL:filename.c_str(), "open directory dialog",  "Choose a directory" );
01188     if (s.length() > 0)
01189       {
01190         gnuplot_directory = s.ascii();
01191         if (gnuplot_directory.at(gnuplot_directory.size()-1) != '/') gnuplot_directory+="/";
01192 
01193         getSimulation()->gnuplotDirectory.setValue(gnuplot_directory);
01194         setExportGnuplot(exportGnuplotFilesCheckbox->isChecked());
01195       }
01196       }
01197 
01198 
01199       void RealGUI::setTitle ( std::string windowTitle )
01200       {
01201     std::string str = "Sofa";
01202     if ( !windowTitle.empty() )
01203       {
01204         str += " - ";
01205         str += windowTitle;
01206       }
01207 #ifdef WIN32
01208     setWindowTitle ( str.c_str() );
01209 #else
01210     setCaption ( str.c_str() );
01211 #endif
01212       }
01213 
01214 
01215       void RealGUI::playpauseGUI ( bool value )
01216       {
01217     startButton->setOn ( value );
01218     if ( value ) {timerStep->start ( 0 );}
01219     else {timerStep->stop();}
01220     if ( getScene() )  getScene()->getContext()->setAnimate ( value );
01221       }
01222 
01223 
01224       void RealGUI::setGUI ( void )
01225       {
01226     textEdit1->setText ( viewer->helpString() );
01227 /*
01228 #ifdef SOFA_GUI_QTOGREVIEWER
01229     //Hide unused options
01230     if ( !strcmp ( viewerName,"ogre" ) )
01231       {
01232         showVisual->hide();
01233         showBehavior->hide();
01234         showCollision->hide();
01235         showBoundingCollision->hide();
01236         showMapping->hide();
01237         showMechanicalMapping->hide();
01238         showForceField->hide();
01239         showInteractionForceField->hide();
01240         showWireFrame->hide();
01241         showNormals->hide();
01242       }
01243     else
01244       {
01245         showVisual->show();
01246         showBehavior->show();
01247         showCollision->show();
01248         showBoundingCollision->show();
01249         showMapping->show();
01250         showMechanicalMapping->show();
01251         showForceField->show();
01252         showInteractionForceField->show();
01253         showWireFrame->show();
01254         showNormals->show();
01255       }
01256 #endif*/
01257       }
01258       //###################################################################################################################
01259 
01260 
01261       //*****************************************************************************************
01262       //called at each step of the rendering
01263 
01264       void RealGUI::step()
01265       {
01266     GNode* groot = viewer->getScene();
01267     if ( groot == NULL ) return;
01268 
01269 
01270       {
01271         if ( viewer->ready() ) return;
01272         //groot->setLogTime(true);
01273 
01274         getSimulation()->animate ( groot );
01275 
01276         if ( m_dumpState )
01277           getSimulation()->dumpState ( groot, *m_dumpStateStream );
01278         if ( m_exportGnuplot )
01279           getSimulation()->exportGnuplot ( groot, groot->getTime() );
01280 
01281         viewer->wait();
01282 
01283         eventNewStep();
01284         eventNewTime();
01285 
01286 #ifdef SOFA_QT4
01287         viewer->getQWidget()->setUpdatesEnabled ( true );
01288 #endif
01289         viewer->getQWidget()->update();
01290         if (currentTab == TabStats) graphCreateStats(viewer->getScene());
01291       }
01292 
01293 
01294     if ( _animationOBJ )
01295       {
01296 #ifdef CAPTURE_PERIOD
01297         static int counter = 0;
01298         if ( ( counter++ % CAPTURE_PERIOD ) ==0 )
01299 #endif
01300           {
01301         exportOBJ ( false );
01302         ++_animationOBJcounter;
01303           }
01304       }
01305     emit newStep();
01306       }
01307 
01308       //*****************************************************************************************
01309       // Update sofa Simulation with the time step
01310 
01311       void RealGUI::eventNewStep()
01312       {
01313     static ctime_t beginTime[10];
01314     static const ctime_t timeTicks = CTime::getRefTicksPerSec();
01315     Node* groot = getScene();
01316     if ( frameCounter==0 )
01317       {
01318         ctime_t t = CTime::getRefTime();
01319         for ( int i=0;i<10;i++ )
01320           beginTime[i] = t;
01321       }
01322     ++frameCounter;
01323     if ( ( frameCounter%10 ) == 0 )
01324       {
01325         ctime_t curtime = CTime::getRefTime();
01326         int i = ( ( frameCounter/10 ) %10 );
01327         double fps = ( ( double ) timeTicks / ( curtime - beginTime[i] ) ) * ( frameCounter<100?frameCounter:100 );
01328         //      emit newFPS(fps);
01329         char buf[100];
01330         sprintf ( buf, "%.1f FPS", fps );
01331         fpsLabel->setText ( buf );
01332         //      emit newFPS(buf);
01333         beginTime[i] = curtime;
01334         //frameCounter = 0;
01335       }
01336 
01337     if ( m_displayComputationTime && ( frameCounter%100 ) == 0 && groot!=NULL )
01338       {
01339 
01340         std::cout << "========== ITERATION " << frameCounter << " ==========\n";
01341         const sofa::simulation::Node::NodeTimer& total = groot->getTotalTime();
01342         const std::map<std::string, sofa::simulation::Node::NodeTimer>& times = groot->getVisitorTime();
01343         const std::map<std::string, std::map<sofa::core::objectmodel::BaseObject*, sofa::simulation::Node::ObjectTimer> >& objtimes = groot->getObjectTime();
01344         const double fact = 1000000.0 / ( 100*groot->getTimeFreq() );
01345         for ( std::map<std::string, sofa::simulation::Node::NodeTimer>::const_iterator it = times.begin(); it != times.end(); ++it )
01346           {
01347         std::cout << "TIME "<<it->first<<": " << ( ( int ) ( fact*it->second.tTree+0.5 ) ) *0.001 << " ms (" << ( 1000*it->second.tTree/total.tTree ) *0.1 << " %).\n";
01348         std::map<std::string, std::map<sofa::core::objectmodel::BaseObject*, sofa::simulation::Node::ObjectTimer> >::const_iterator it1 = objtimes.find ( it->first );
01349         if ( it1 != objtimes.end() )
01350           {
01351             for ( std::map<sofa::core::objectmodel::BaseObject*, sofa::simulation::Node::ObjectTimer>::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 )
01352               {
01353             std::cout << "  "<< sofa::helper::gettypename ( typeid ( * ( it2->first ) ) ) <<" "<< it2->first->getName() <<": "
01354                   << ( ( int ) ( fact*it2->second.tObject+0.5 ) ) *0.001 << " ms (" << ( 1000*it2->second.tObject/it->second.tTree ) *0.1 << " %).\n";
01355               }
01356           }
01357           }
01358         for ( std::map<std::string, std::map<sofa::core::objectmodel::BaseObject*, sofa::simulation::Node::ObjectTimer> >::const_iterator it = objtimes.begin(); it != objtimes.end(); ++it )
01359           {
01360         if ( times.count ( it->first ) >0 ) continue;
01361         ctime_t ttotal = 0;
01362         for ( std::map<sofa::core::objectmodel::BaseObject*, sofa::simulation::Node::ObjectTimer>::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 )
01363           ttotal += it2->second.tObject;
01364         std::cout << "TIME "<<it->first<<": " << ( ( int ) ( fact*ttotal+0.5 ) ) *0.001 << " ms (" << ( 1000*ttotal/total.tTree ) *0.1 << " %).\n";
01365         if ( ttotal > 0 )
01366           for ( std::map<sofa::core::objectmodel::BaseObject*, sofa::simulation::Node::ObjectTimer>::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2 )
01367             {
01368               std::cout << "  "<< sofa::helper::gettypename ( typeid ( * ( it2->first ) ) ) <<" "<< it2->first->getName() <<": "
01369                 << ( ( int ) ( fact*it2->second.tObject+0.5 ) ) *0.001 << " ms (" << ( 1000*it2->second.tObject/ttotal ) *0.1 << " %).\n";
01370             }
01371           }
01372         std::cout << "TOTAL TIME: " << ( ( int ) ( fact*total.tTree+0.5 ) ) *0.001 << " ms (" << ( ( int ) ( 100/ ( fact*total.tTree*0.000001 ) +0.5 ) ) *0.01 << " FPS).\n";
01373         groot->resetTime();
01374 
01375       }
01376       }
01377 
01378 
01379 
01380       void RealGUI::eventNewTime()
01381       {
01382     Node* groot = getScene();
01383     if ( groot )
01384       {
01385 
01386         double time = groot->getTime();
01387         char buf[100];
01388         sprintf ( buf, "Time: %.3f s", time );
01389         timeLabel->setText ( buf );
01390 
01391         if (record_simulation)
01392           {
01393         setRecordTime(time);
01394         double final_time = getRecordFinalTime();
01395 
01396         if ((int)(1000*final_time) < (int)(1000*time))
01397           {
01398             setRecordFinalTime(time);
01399             timeSlider->setMaxValue(timeSlider->maxValue()+1);
01400             timeSlider->setValue(timeSlider->maxValue());
01401           }
01402         else
01403           {
01404             timeSlider->setValue(timeSlider->value()+1);
01405           }
01406         timeSlider->update();
01407           }
01408       }
01409       }
01410 
01411 
01412 
01413 
01414       //*****************************************************************************************
01415       // Set the time between each iteration of the Sofa Simulation
01416 
01417       void RealGUI::setDt ( double value )
01418       {
01419     Node* groot = getScene();
01420     if ( value > 0.0 )
01421       {
01422 
01423         if ( groot )
01424           groot->getContext()->setDt ( value );
01425       }
01426       }
01427 
01428       void RealGUI::setDt ( const QString& value )
01429       {
01430     setDt ( value.toDouble() );
01431       }
01432 
01433 
01434       //*****************************************************************************************
01435       // Reset the simulation to t=0
01436       void RealGUI::resetScene()
01437       {
01438     GNode* groot = getScene();
01439 
01440     //Hide the dialog to add a new object in the graph
01441     if ( dialog != NULL ) dialog->hide();
01442     //Hide all the dialogs to modify the graph
01443     emit ( newScene() );
01444 
01445     //Clear the list of modified dialog opened
01446     current_Id_modifyDialog=0;
01447     map_modifyDialogOpened.clear();
01448 
01449 
01450     std::list< GNode *>::iterator it;
01451     //**************************************************************
01452     //GRAPH MANAGER
01453     bool isFrozen = graphListener->frozen;
01454     graphListener->unfreeze ( groot );
01455     std::map<core::objectmodel::Base*, Q3ListViewItem* >::iterator graph_iterator;
01456 
01457 
01458     //Remove all the objects added
01459     bool node_removed ;
01460     for ( it=list_object_added.begin(); it != list_object_added.end(); it++ )
01461       {
01462         node_removed = false;
01463 
01464         //Verify if they have not been removed before
01465         std::list< GNode *>::iterator it_removed;
01466         for ( it_removed=list_object_removed.begin();it_removed != list_object_removed.end();it_removed++ )
01467           {
01468         if ( ( *it_removed ) == ( *it ) ) { node_removed=true;continue;} //node already removed
01469           }
01470         if ( node_removed ) continue;
01471         ( *it )->getParent()->removeChild ( ( *it ) );
01472         graphListener->removeChild ( NULL, ( *it ) );
01473         delete ( *it );
01474       }
01475 
01476     list_object_added.clear();
01477 
01478 
01479     //Add all the objects present at initial time
01480     //Begin from the last removed item: the last one can be the parent of one removed lately in the simulation
01481     it=list_object_removed.end();
01482 
01483     while ( true )
01484       {
01485         if ( it == list_object_removed.begin() ) break;
01486         --it;
01487         std::list< GNode *>::iterator it_initial;
01488         for ( it_initial=list_object_initial.begin();it_initial != list_object_initial.end();it_initial++ )
01489           {
01490         if ( ( *it_initial ) == ( *it ) )
01491           {
01492             it_initial++; //points to the parent of the node
01493             ( *it_initial )->addChild ( ( *it ) );
01494             graphListener->addObject ( dynamic_cast<GNode *> ( *it_initial ), ( core::objectmodel::BaseObject* ) ( *it ) );
01495             continue;
01496           }
01497         //We have to increment 2 times the iterator: le list_object_initial contains first the node, then its father
01498         it_initial++;
01499           }
01500       }
01501 
01502     list_object_removed.clear();
01503 
01504 
01505 
01506 
01507     if ( isFrozen ) graphListener->freeze ( groot );
01508 
01509     //Reset the scene
01510     if ( groot )
01511       {
01512         getSimulation()->reset ( groot );
01513         groot->setTime(initial_time);
01514         eventNewTime();
01515 
01516         //viewer->resetView();
01517         viewer->getQWidget()->update();
01518       }
01519       }
01520 
01521 
01522       //*****************************************************************************************
01523       //
01524       void RealGUI::exportGraph()
01525       {
01526     exportGraph ( getScene() );
01527       }
01528 
01529 
01530       void RealGUI::exportGraph ( sofa::simulation::tree::GNode* root )
01531       {
01532 
01533     if ( root == NULL ) return;
01534     sofa::gui::qt::GenGraphForm* form = new sofa::gui::qt::GenGraphForm;
01535     form->setScene ( root );
01536     form->show();
01537       }
01538 
01539 
01540 
01541       //*****************************************************************************************
01542       //
01543       void RealGUI::displayComputationTime ( bool value )
01544       {
01545     Node* groot = getScene();
01546     m_displayComputationTime = value;
01547     if ( groot )
01548       {
01549         groot->setLogTime ( m_displayComputationTime );
01550       }
01551       }
01552 
01553 
01554 
01555       //*****************************************************************************************
01556       //
01557       void RealGUI::setExportGnuplot ( bool exp )
01558       {
01559     GNode* groot = getScene();
01560     m_exportGnuplot = exp;
01561     if ( m_exportGnuplot && groot )
01562       {
01563         getSimulation()->initGnuplot ( groot );
01564         getSimulation()->exportGnuplot ( groot, groot->getTime() );
01565       }
01566       }
01567 
01568 
01569       //*****************************************************************************************
01570       //
01571       void RealGUI::dumpState ( bool value )
01572       {
01573     m_dumpState = value;
01574     if ( m_dumpState )
01575       {
01576         m_dumpStateStream = new std::ofstream ( "dumpState.data" );
01577       }
01578     else if ( m_dumpStateStream!=NULL )
01579       {
01580         delete m_dumpStateStream;
01581         m_dumpStateStream = 0;
01582       }
01583       }
01584 
01585 
01586 
01587       //*****************************************************************************************
01588       //
01589       void RealGUI::exportOBJ ( bool exportMTL )
01590       {
01591     GNode* groot = getScene();
01592     if ( !groot ) return;
01593     std::string sceneFileName = viewer->getSceneFileName();
01594     std::ostringstream ofilename;
01595     if ( !sceneFileName.empty() )
01596       {
01597         const char* begin = sceneFileName.c_str();
01598         const char* end = strrchr ( begin,'.' );
01599         if ( !end ) end = begin + sceneFileName.length();
01600         ofilename << std::string ( begin, end );
01601       }
01602     else
01603       ofilename << "scene";
01604 
01605     std::stringstream oss;
01606     oss.width ( 5 );
01607     oss.fill ( '0' );
01608     oss << _animationOBJcounter;
01609 
01610     ofilename << '_' << ( oss.str().c_str() );
01611     ofilename << ".obj";
01612     std::string filename = ofilename.str();
01613     std::cout << "Exporting OBJ Scene "<<filename<<std::endl;
01614     getSimulation()->exportOBJ ( groot, filename.c_str(),exportMTL );
01615       }
01616 
01617 
01618       //*****************************************************************************************
01619       // Called by the animate timer
01620       void RealGUI::animate()
01621       {
01622     viewer->getQWidget()->update();
01623       }
01624 
01625 
01626       void RealGUI::keyPressEvent ( QKeyEvent * e )
01627       {
01628       // ignore if there are modifiers (i.e. CTRL of SHIFT)
01629 #ifdef SOFA_QT4
01630       if (e->modifiers()) return;
01631 #else
01632       if (e->state() & (Qt::KeyButtonMask)) return;
01633 #endif
01634     switch ( e->key() )
01635       {
01636 
01637       case Qt::Key_O:
01638         // --- export to OBJ
01639         {
01640           exportOBJ();
01641           break;
01642         }
01643       case Qt::Key_P:
01644         // --- export to a succession of OBJ to make a video
01645         {
01646           _animationOBJ = !_animationOBJ;
01647           _animationOBJcounter = 0;
01648           break;
01649         }
01650       case Qt::Key_Escape:
01651         {
01652           emit(quit());
01653           break;
01654         }
01655       default:
01656         {
01657           e->ignore();
01658           break;
01659         }
01660       }
01661       }
01662 
01663 
01664       /*****************************************************************************************************************/
01665       //Translate an object
01666       void RealGUI::transformObject ( Node *node, double dx, double dy, double dz,  double rx, double ry, double rz, double scale )
01667       {
01668     if ( node == NULL ) return;
01669     const SReal conversionDegRad = 3.141592653/180.0;
01670     Vector3 rotationVector = Vector3(rx,ry,rz)*conversionDegRad;
01671 
01672     TransformationVisitor transform;
01673     transform.setTranslation(dx,dy,dz);
01674     transform.setRotation(rx,ry,rz);
01675     transform.setScale(scale);
01676     transform.execute(node);
01677 
01678       }
01679 
01680       /*****************************************************************************************************************/
01681       void RealGUI::loadObject ( std::string path, double dx, double dy, double dz,  double rx, double ry, double rz,double scale )
01682       {
01683     //Verify if the file exists
01684     if ( !sofa::helper::system::DataRepository.findFile ( path ) )
01685     {
01686       return;
01687     }
01688     path = sofa::helper::system::DataRepository.getFile ( path );
01689 
01690     //Desactivate the animate-> no more graph modification
01691 
01692     bool isAnimated = startButton->isOn();
01693 
01694     playpauseGUI ( false );
01695     //If we add the object without clicking on the graph (direct use of the method),
01696     //the object will be added to the root node
01697     if ( node_clicked == NULL )
01698       {
01699         for ( std::map<core::objectmodel::Base*, Q3ListViewItem* >::iterator it = graphListener->items.begin() ; it != graphListener->items.end() ; ++ it )
01700           {
01701         if ( ( *it ).second->itemPos() == 0 ) //Root node position
01702           {
01703             node_clicked = dynamic_cast< sofa::simulation::tree::GNode *> ( ( *it ).first );
01704             break;
01705           }
01706           }
01707         if ( node_clicked == NULL ) return;
01708       }
01709 
01710     //We allow unlock the graph to make all the changes now
01711     if ( currentTab != TabGraph )
01712       graphListener->unfreeze ( node_clicked );
01713 
01714     //Loading of the xml file
01715     xml::BaseElement* xml = xml::loadFromFile ( path.c_str() );
01716     if ( xml == NULL ) return;
01717 
01718 
01719     helper::system::SetDirectory chdir ( path.c_str() );
01720 
01721     //std::cout << "Initializing objects"<<std::endl;
01722     if ( !xml->init() )
01723       {
01724         std::cerr << "Objects initialization failed."<<std::endl;
01725       }
01726 
01727     GNode* new_node = dynamic_cast<GNode*> ( xml->getObject() );
01728     if ( new_node == NULL )
01729       {
01730         std::cerr << "Objects initialization failed."<<std::endl;
01731         delete xml;
01732         return ;
01733       }
01734 
01735     //std::cout << "Initializing simulation "<<new_node->getName() <<std::endl;
01736     new_node->execute<InitVisitor>();
01737 
01738     if ( node_clicked->child.begin() ==  node_clicked->child.end() &&  node_clicked->object.begin() == node_clicked->object.end() )
01739       {
01740         //Temporary Root : the current graph is empty, and has only a single node "Root"
01741         viewer->setScene ( new_node, path.c_str() );
01742         graphListener->removeChild ( NULL, node_clicked );
01743         graphListener->addChild ( NULL, new_node );
01744       }
01745     else
01746       {
01747         node_clicked->addChild ( new_node );
01748         graphListener->addObject ( node_clicked, ( core::objectmodel::BaseObject* ) new_node );
01749 
01750         list_object_added.push_back ( new_node );
01751       }
01752 
01753     //update the stats graph
01754     graphCreateStats(viewer->getScene());
01755     //Apply the Transformation
01756     transformObject ( new_node, dx, dy, dz, rx,ry,rz,scale );
01757 
01758     //Update the view
01759     viewer->resetView();
01760     viewer->getQWidget()->update();
01761 
01762     //freeze the graph if needed and animate
01763     if ( currentTab != TabGraph )
01764       graphListener->freeze ( node_clicked );
01765 
01766     node_clicked = NULL;
01767     item_clicked = NULL;
01768     playpauseGUI ( isAnimated );
01769       }
01770 
01771 
01772       void RealGUI::dropEvent(QDropEvent* event)
01773       {
01774       QString text;
01775       Q3TextDrag::decode(event, text);
01776       std::string filename(text.ascii());
01777 #ifdef WIN32
01778       filename = filename.substr(8); //removing file:///
01779 #else
01780       filename = filename.substr(7); //removing file://
01781 #endif
01782 
01783       if (filename[filename.size()-1] == '\n')
01784         {
01785           filename.resize(filename.size()-1);
01786           filename[filename.size()-1]='\0';
01787         }
01788 
01789       if (filename.rfind(".simu") != std::string::npos) fileOpenSimu(filename);
01790       else                                          fileOpen(filename);
01791       }
01792 
01793 
01794 
01795       void RealGUI::showhideElements(int FILTER, bool value)
01796       {     
01797     Node* groot = getScene();
01798     if ( groot )
01799       {
01800         switch(FILTER)
01801           {
01802           case DisplayFlagWidget::ALL:        
01803         groot->getContext()->setShowVisualModels ( value );
01804         groot->getContext()->setShowBehaviorModels ( value );
01805         groot->getContext()->setShowCollisionModels ( value );
01806         groot->getContext()->setShowBoundingCollisionModels ( value );  
01807         groot->getContext()->setShowMappings ( value );
01808         groot->getContext()->setShowMechanicalMappings ( value );
01809         groot->getContext()->setShowForceFields ( value );
01810         groot->getContext()->setShowInteractionForceFields ( value );
01811         break; 
01812           case  DisplayFlagWidget::VISUAL:            groot->getContext()->setShowVisualModels ( value ); break;
01813           case  DisplayFlagWidget::BEHAVIOR:          groot->getContext()->setShowBehaviorModels ( value ); break;
01814           case  DisplayFlagWidget::COLLISION:         groot->getContext()->setShowCollisionModels ( value ); break;
01815           case  DisplayFlagWidget::BOUNDING:          groot->getContext()->setShowBoundingCollisionModels ( value );  break;
01816           case  DisplayFlagWidget::MAPPING:           groot->getContext()->setShowMappings ( value ); break;
01817           case  DisplayFlagWidget::MECHANICALMAPPING: groot->getContext()->setShowMechanicalMappings ( value ); break;
01818           case  DisplayFlagWidget::FORCEFIELD:        groot->getContext()->setShowForceFields ( value ); break;
01819           case  DisplayFlagWidget::INTERACTION:       groot->getContext()->setShowInteractionForceFields ( value );break;
01820           case  DisplayFlagWidget::WIREFRAME:         groot->getContext()->setShowWireFrame ( value );break;
01821           case  DisplayFlagWidget::NORMALS:           groot->getContext()->setShowNormals ( value );break;
01822           }
01823         sofa::simulation::tree::getSimulation()->updateVisualContext ( groot, FILTER );
01824       }
01825     viewer->getQWidget()->update();
01826       }
01827 
01828 
01829     } // namespace qt
01830 
01831   } // namespace gui
01832 
01833 } // namespace sofa

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