SofaViewer.h

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 #ifndef SOFA_VIEWER_H
00028 #define SOFA_VIEWER_H
00029 
00030 #include <qstring.h>
00031 #include <qwidget.h>
00032 
00033 
00034 
00035 #ifdef SOFA_QT4 
00036 #include <QEvent>
00037 #include <QMouseEvent> 
00038 #include <QKeyEvent>
00039 #else
00040 #include <qevent.h>
00041 #endif
00042 
00043 
00044 #include <sofa/helper/gl/Capture.h>
00045 #include <sofa/core/objectmodel/KeypressedEvent.h>
00046 #include <sofa/core/objectmodel/KeyreleasedEvent.h>
00047 #include <sofa/core/objectmodel/MouseEvent.h>
00048 #include <sofa/component/collision/RayPickInteractor.h>
00049 
00050 //instruments handling
00051 #include <sofa/component/controller/Controller.h>
00052 #include <sofa/defaulttype/LaparoscopicRigidTypes.h>
00053 //#include <sofa/simulation/common/GrabVisitor.h>
00054 #include <sofa/simulation/common/MechanicalVisitor.h>
00055 #include <sofa/simulation/common/UpdateMappingVisitor.h>
00056 #include <sofa/simulation/tree/Simulation.h>
00057 #ifdef SOFA_QT4
00058 #include <QEvent>
00059 #include <QMouseEvent>
00060 #include <QKeyEvent>
00061 #else
00062 #include <qevent.h>
00063 #endif
00064 
00065 namespace sofa
00066 {
00067 
00068   namespace gui
00069   {
00070 
00071     namespace qt
00072     {
00073 
00074       namespace viewer
00075       {
00076 
00077     using namespace sofa::defaulttype;
00078     enum {
00079       BTLEFT_MODE = 101,
00080       BTRIGHT_MODE = 102,
00081       BTMIDDLE_MODE = 103,
00082     };
00083 
00084     enum {CAMERA_PERSPECTIVE, CAMERA_ORTHOGRAPHIC};
00085       
00086     class SofaViewer
00087 
00088 
00089       {
00090 
00091       public:
00092         SofaViewer ()
00093           : groot(NULL), m_isControlPressed(false), _video(false), _shadow(false), _gl_shadow(false), _axis(false), camera_type(CAMERA_PERSPECTIVE)
00094         {}
00095         virtual ~SofaViewer(){}
00096 
00097         virtual QWidget* getQWidget()=0;
00098 
00099         virtual sofa::simulation::tree::GNode* getScene()        {  return groot;}
00100         virtual const std::string&             getSceneFileName(){  return sceneFileName;}
00101         virtual void                           setSceneFileName(const std::string &f){sceneFileName = f;};
00102 
00103         virtual void setup() {}
00104         virtual void setScene(sofa::simulation::tree::GNode* scene, const char* filename=NULL, bool /*keepParams*/=false)
00105             {
00106 //               if (interactor != NULL) delete interactor;
00107               //interactor = NULL;
00108               scene->getContext()->get( interactor);
00109               std::ostringstream ofilename;
00110               std::string screenshot_prefix;
00111 
00112               sceneFileName = (filename==NULL)?"":filename;
00113               if (!sceneFileName.empty())
00114               {
00115                 const char* begin = sceneFileName.c_str();
00116                 const char* end = strrchr(begin,'.');
00117                 if (!end) end = begin + sceneFileName.length();
00118                 ofilename << std::string(begin, end);
00119                 ofilename << "_";
00120 
00121                 screenshot_prefix = ofilename.str();
00122 
00123         std::string::size_type position_scene = screenshot_prefix.rfind("scenes/");
00124 
00125                 if (position_scene != std::string::npos && position_scene < screenshot_prefix.size()-7)
00126                 {
00127                   screenshot_prefix.replace(position_scene, 7, "share/screenshots/");
00128                 }
00129               }
00130               else
00131                 screenshot_prefix = "scene_";
00132               capture.setPrefix(screenshot_prefix);
00133 
00134               groot = scene;
00135               initTexturesDone = false;
00136               sceneBBoxIsValid = true;
00137                //if (!keepParams) resetView();
00138             }
00139             
00140             
00141         virtual void resetView()=0;
00142         virtual QString helpString()=0;
00143         virtual bool ready() { return true; }
00144         virtual void wait() {}
00145 
00146         //Fonctions needed to take a screenshot
00147         virtual const std::string screenshotName(){ return capture.findFilename().c_str();};
00148         virtual void        setPrefix(const std::string filename){capture.setPrefix(filename);};    
00149         virtual void        screenshot(const std::string filename, int compression_level = -1)
00150         {         
00151           capture.saveScreen(filename, compression_level);
00152         }
00153 
00154       protected:
00155 
00156 
00157 
00158         // ---------------------- Here are the Keyboard controls   ----------------------
00159         void keyPressEvent ( QKeyEvent * e )
00160         {
00161           switch(e->key())
00162         {
00163         case Qt::Key_B:
00164           // --- change background
00165           {
00166             _background = (_background+1)%3;
00167             break;
00168           }
00169         case Qt::Key_L:
00170           // --- draw shadows
00171           {
00172             if (_gl_shadow) _shadow = !_shadow;
00173             break;
00174           }     
00175         case Qt::Key_R:
00176           // --- draw axis
00177           {
00178             _axis = !_axis;
00179             break;
00180           }
00181         case Qt::Key_S: 
00182           {
00183             screenshot(capture.findFilename());
00184             break;
00185           }
00186         case Qt::Key_T:
00187         {
00188             if (camera_type == CAMERA_PERSPECTIVE) 
00189                 camera_type = CAMERA_ORTHOGRAPHIC;
00190             else                                   
00191                 camera_type = CAMERA_PERSPECTIVE;
00192             break;
00193         }
00194         case Qt::Key_V:
00195         // --- save video
00196         {
00197             _video = !_video;
00198             capture.setCounter();
00199             break;
00200         }
00201         case Qt::Key_W:
00202         // --- save current view
00203         {
00204             saveView();
00205             break;
00206         }
00207         case Qt::Key_Control:
00208           {
00209             m_isControlPressed = true;
00210             //cerr<<"QtViewer::keyPressEvent, CONTROL pressed"<<endl;
00211             break;
00212           }
00213         default:
00214           {
00215             e->ignore();
00216           }
00217         }
00218         }
00219 
00220         
00221         void keyReleaseEvent ( QKeyEvent * e )
00222         {
00223             
00224             switch(e->key())
00225             {
00226                 case Qt::Key_Control:
00227                 {
00228                     m_isControlPressed = false;
00229 
00230                     // Send Control Release Info to a potential ArticulatedRigid Instrument
00231                     sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::Reset);
00232                     if (groot)
00233                         groot->propagateEvent(&mouseEvent);
00234                 }
00235                 default:
00236                 {
00237                     e->ignore();
00238                 }
00239             }
00240 
00241             if( isControlPressed() )
00242             {
00243                 sofa::core::objectmodel::KeyreleasedEvent keyEvent(e->key());
00244                 if (groot) 
00245                     groot->propagateEvent(&keyEvent);
00246             }
00247         }
00248 
00249       
00250 
00251 
00252         bool isControlPressed() const {
00253           return m_isControlPressed;
00254         }
00255 
00256 
00257 
00258         // ---------------------- Here are the Mouse controls   ----------------------
00259         
00260         void mouseEvent( QMouseEvent *e)
00261         {
00262           if (e->state()&Qt::ShiftButton)
00263         {
00264           //_sceneTransform.ApplyInverse();
00265           if (interactor==NULL)
00266             {
00267               interactor = new sofa::component::collision::RayPickInteractor();
00268               interactor->setName("mouse");
00269               if (groot)
00270             {
00271               simulation::tree::GNode* child = new simulation::tree::GNode("mouse");
00272               groot->addChild(child);
00273               child->addObject(interactor);
00274             }
00275               interactor->init();
00276             }
00277           interactor->newEvent("show");
00278           switch (e->type())
00279             {
00280             case QEvent::MouseButtonPress:
00281               if (e->button() == Qt::LeftButton)
00282             {
00283               interactor->newEvent("pick"); // Shift+Leftclick to deform the mesh
00284             }
00285               else if (e->button() == Qt::RightButton) // Shift+Rightclick to remove triangles
00286             {
00287               interactor->newEvent("pick2");
00288             }
00289               else if (e->button() == Qt::MidButton) // Shift+Midclick (by 2 steps defining 2 input points) to cut from one point to another
00290             {
00291               interactor->newEvent("pick3");
00292             }
00293               break;
00294             case QEvent::MouseButtonRelease:
00295               //if (e->button() == Qt::LeftButton)
00296               {
00297             interactor->newEvent("release");
00298               }
00299               break;
00300             default: break;
00301             }
00302           moveRayPickInteractor(e->x(), e->y());
00303         }
00304 
00305         }
00306 
00307         // ---------------------- Here are the controls for instruments  ----------------------
00308 
00309         void moveLaparoscopic( QMouseEvent *e)
00310         {
00311             int index_instrument = simulation::tree::getSimulation()->instrumentInUse.getValue();
00312             if (index_instrument < 0 || index_instrument > (int)simulation::tree::getSimulation()->instruments.size()) return;
00313           
00314             simulation::Node *instrument = simulation::tree::getSimulation()->instruments[index_instrument];
00315             if (instrument == NULL) return;
00316           
00317             int eventX = e->x();
00318             int eventY = e->y();
00319 
00320             std::vector< sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* > instruments;
00321             instrument->getTreeObjects<sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>, std::vector< sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* > >(&instruments);
00322           
00323             if (!instruments.empty())
00324             {
00325                 sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* instrument = instruments[0];
00326                 switch (e->type())
00327                 {
00328                     case QEvent::MouseButtonPress:
00329                         // Mouse left button is pushed
00330                         if (e->button() == Qt::LeftButton)
00331                         {
00332                             _navigationMode = BTLEFT_MODE;
00333                             _mouseInteractorMoving = true;
00334                             _mouseInteractorSavedPosX = eventX;
00335                             _mouseInteractorSavedPosY = eventY;
00336                         }
00337                         // Mouse right button is pushed 
00338                         else if (e->button() == Qt::RightButton)
00339                         {
00340                             _navigationMode = BTRIGHT_MODE;
00341                             _mouseInteractorMoving = true;
00342                             _mouseInteractorSavedPosX = eventX;
00343                             _mouseInteractorSavedPosY = eventY;
00344                         }
00345                         // Mouse middle button is pushed 
00346                         else if (e->button() == Qt::MidButton)
00347                         {
00348                             _navigationMode = BTMIDDLE_MODE;
00349                             _mouseInteractorMoving = true;
00350                             _mouseInteractorSavedPosX = eventX;
00351                             _mouseInteractorSavedPosY = eventY;
00352                         }
00353                         break;
00354 
00355                     case QEvent::MouseMove:
00356                         // 
00357                         break;
00358 
00359                     case QEvent::MouseButtonRelease:
00360                         // Mouse left button is released 
00361                         if (e->button() == Qt::LeftButton)
00362                         {
00363                             if (_mouseInteractorMoving)
00364                             {
00365                                 _mouseInteractorMoving = false;
00366                             }
00367                         }
00368                         // Mouse right button is released
00369                         else if (e->button() == Qt::RightButton)
00370                         {
00371                             if (_mouseInteractorMoving)
00372                             {
00373                                 _mouseInteractorMoving = false;
00374                             }
00375                         }
00376                         // Mouse middle button is released
00377                         else if (e->button() == Qt::MidButton)
00378                         {
00379                             if (_mouseInteractorMoving)
00380                             {
00381                                 _mouseInteractorMoving = false;
00382                                 //static_cast<sofa::simulation::tree::GNode*>(instrument->getContext())->execute<sofa::simulation::GrabVisitor>();
00383                             }
00384                         }
00385                         break;
00386 
00387                     default:
00388                         break;
00389                 }
00390               
00391                 if (_mouseInteractorMoving && _navigationMode == BTLEFT_MODE)
00392                 {
00393                     int dx = eventX - _mouseInteractorSavedPosX;
00394                     int dy = eventY - _mouseInteractorSavedPosY;
00395                     if (dx || dy)
00396                     {
00397                         (*instrument->getX())[0].getOrientation() = (*instrument->getX())[0].getOrientation() * Quat(Vector3(0,1,0),dx*0.001) * Quat(Vector3(0,0,1),dy*0.001);
00398                         _mouseInteractorSavedPosX = eventX;
00399                         _mouseInteractorSavedPosY = eventY;
00400                     }
00401                 }
00402                 else if (_mouseInteractorMoving && _navigationMode == BTMIDDLE_MODE)
00403                 {
00404                     int dx = eventX - _mouseInteractorSavedPosX;
00405                     int dy = eventY - _mouseInteractorSavedPosY;
00406                     if (dx || dy)
00407                     {
00408                         _mouseInteractorSavedPosX = eventX;
00409                         _mouseInteractorSavedPosY = eventY;
00410                     }
00411                 }
00412                 else if (_mouseInteractorMoving && _navigationMode == BTRIGHT_MODE)
00413                 {
00414                     int dx = eventX - _mouseInteractorSavedPosX;
00415                     int dy = eventY - _mouseInteractorSavedPosY;
00416                     if (dx || dy)
00417                     {
00418                         (*instrument->getX())[0].getTranslation() += (dy)*0.01;
00419                         (*instrument->getX())[0].getOrientation() = (*instrument->getX())[0].getOrientation() * Quat(Vector3(1,0,0),dx*0.001);
00420                         _mouseInteractorSavedPosX = eventX;
00421                         _mouseInteractorSavedPosY = eventY;
00422                     }
00423                 }
00424               
00425                 static_cast<sofa::simulation::tree::GNode*>(instrument->getContext())->execute<sofa::simulation::MechanicalPropagatePositionAndVelocityVisitor>();
00426                 static_cast<sofa::simulation::tree::GNode*>(instrument->getContext())->execute<sofa::simulation::UpdateMappingVisitor>();
00427                 getQWidget()->update();
00428             }
00429             else
00430             {
00431                 std::vector< component::controller::Controller* > bc;
00432                 instrument->getTreeObjects<component::controller::Controller, std::vector< component::controller::Controller* > >(&bc);
00433 
00434                 if (!bc.empty())
00435                 {   
00436                     switch (e->type())
00437                     {
00438                         case QEvent::MouseButtonPress:
00439                             // Mouse left button is pushed
00440                             if (e->button() == Qt::LeftButton)
00441                             {
00442                                 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::LeftPressed, eventX, eventY);
00443                                 if (groot)
00444                                     groot->propagateEvent(&mouseEvent);
00445                             }
00446                             // Mouse right button is pushed 
00447                             else if (e->button() == Qt::RightButton)
00448                             {
00449                                 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::RightPressed, eventX, eventY);
00450                                 if (groot)
00451                                     groot->propagateEvent(&mouseEvent);
00452                             }
00453                             // Mouse middle button is pushed 
00454                             else if (e->button() == Qt::MidButton)
00455                             {
00456 
00457                             }
00458                             break;
00459 
00460                         case QEvent::MouseMove:
00461                             {
00462                                 if (e->state()&(Qt::LeftButton|Qt::RightButton))
00463                                 {
00464                                     sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::Move, eventX, eventY);
00465                                     if (groot)
00466                                         groot->propagateEvent(&mouseEvent);
00467                                 }
00468                             }
00469                             break;
00470 
00471                         case QEvent::MouseButtonRelease:
00472                             // Mouse left button is released 
00473                             if (e->button() == Qt::LeftButton)
00474                             {
00475                                 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::LeftReleased, eventX, eventY);
00476                                 if (groot)
00477                                     groot->propagateEvent(&mouseEvent);
00478                             }
00479                             // Mouse right button is released
00480                             else if (e->button() == Qt::RightButton)
00481                             {
00482                                 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::RightReleased, eventX, eventY);
00483                                 if (groot)
00484                                     groot->propagateEvent(&mouseEvent);
00485                             }
00486                             // Mouse middle button is released
00487                             else if (e->button() == Qt::MidButton)
00488                             {
00489 
00490                             }
00491                             break;
00492 
00493                         default:
00494                             break;
00495                     }
00496 
00497                     getQWidget()->update();
00498                 }
00499             }
00500         }
00501 
00502         void moveLaparoscopic(QWheelEvent *e)
00503         {
00504             int index_instrument = simulation::tree::getSimulation()->instrumentInUse.getValue();
00505             if (index_instrument < 0 || index_instrument > (int)simulation::tree::getSimulation()->instruments.size()) return;
00506           
00507             simulation::Node *instrument = simulation::tree::getSimulation()->instruments[index_instrument];
00508             if (instrument == NULL) return;
00509           
00510             std::vector< component::controller::Controller* > bc;
00511             instrument->getTreeObjects<component::controller::Controller, std::vector< component::controller::Controller* > >(&bc);
00512 
00513             if (!bc.empty())
00514             {   
00515                 sofa::core::objectmodel::MouseEvent mouseEvent(sofa::core::objectmodel::MouseEvent::Wheel, e->delta());
00516                 if (groot)
00517                     groot->propagateEvent(&mouseEvent);
00518                 getQWidget()->update();
00519             }
00520         }
00521 
00522         virtual void moveRayPickInteractor(int , int ){};
00523         
00524         sofa::helper::gl::Capture capture;
00525         sofa::simulation::tree::GNode* groot;
00526         std::string sceneFileName;
00527 
00528         bool m_isControlPressed;
00529         bool _video;
00530         bool _shadow;
00531         bool _gl_shadow;
00532         bool _axis;
00533         int  camera_type;
00534             int _background;
00535             bool initTexturesDone;
00536             bool sceneBBoxIsValid;
00537         sofa::component::collision::RayPickInteractor* interactor;
00538 
00539         //instruments handling
00540         int _navigationMode;
00541         bool _mouseInteractorMoving;
00542         int _mouseInteractorSavedPosX;
00543         int _mouseInteractorSavedPosY;
00544 
00545         //*************************************************************
00546         // QT
00547         //*************************************************************
00548         //SLOTS
00549         virtual void saveView()=0;
00550         virtual void setSizeW(int)=0;
00551         virtual void setSizeH(int)=0;
00552 
00553     
00554         //SIGNALS
00555         virtual void redrawn()=0;
00556         virtual void resizeW( int )=0;
00557         virtual void resizeH( int )=0;
00558 
00559       };
00560       }
00561     }
00562   }
00563 }
00564 
00565 #endif

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